I'm trying to run the following code involving tungstenite and a async_std channel. It works fine when I remove the line below as I commented, but I get an error that's confusing to me when that line is left in.
Could anyone suggest what I should change to get it working?
Basically I want to "catch" any network errors from run_once
, send the error on the channel, and then call run_once
again.
use futures::StreamExt;
async fn run_once(ch:async_std::sync::Sender<String>) -> Result<(), Box<dyn std::error::Error>> {
let (mut ws, _) = async_tungstenite::async_std::connect_async("wss://foo").await?;
loop {
let msg = ws.next().await.ok_or("got none() for ws.next()")??.into_text()?;
ch.send(msg).await;
async_std::task::sleep(std::time::Duration::from_millis(1000)).await;
}
}
async fn run(ch:async_std::sync::Sender<String>) {
while let Err(_) = run_once(ch.clone()).await {
// I don't understand why, but
// commenting the following line gets rid of the problem.
ch.send("error".into()).await;
}
}
fn main() {
let (ch_in, _ch_out) = async_std::sync::channel(1000);
async_std::task::block_on(async {
async_std::task::spawn(run(ch_in));
// actual code does more things here
});
}
error: future cannot be sent between threads safely
--> src/main.rs:23:9
|
23 | async_std::task::spawn(run(ch_in));
| ^^^^^^^^^^^^^^^^^^^^^^ future returned by `run` is not `Send`
|
::: /home/me/.cargo/registry/src/github.com-1ecc6299db9ec823/async-std-1.6.2/src/task/spawn.rs:28:29
|
28 | F: Future<Output = T> + Send + 'static,
| ---- required by this bound in `async_std::task::spawn`
|
= help: the trait `std::marker::Send` is not implemented for `dyn std::error::Error`
note: future is not `Send` as this value is used across an await
--> src/main.rs:16:9
|
13 | while let Err(_) = run_once(ch.clone()).await {
| -------------------------- has type `std::result::Result<(), std::boxed::Box<dyn std::error::Error>>` which is not `Send`
...
16 | ch.send("error".into()).await;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here, with `run_once(ch.clone()).await` maybe used later
17 | }
| - `run_once(ch.clone()).await` is later dropped here
error: aborting due to previous error