I have a bit of code that works exactly as intended:
pub async fn start(num_websockets: i32) {
let messages_received = Arc::new(Mutex::new(0));
let (shutdown_signal, _) = broadcast::channel(1);
let (done, mut wait_for_tasks) = channel::<&str>(1);
tokio::spawn(stats::message_counter(
Arc::clone(&messages_received),
shutdown_signal.subscribe(),
done.clone(),
));
for _i in 0..num_websockets {
let (ws_stream, _) = websocket::connect().await.unwrap();
let (mut write, read) = ws_stream.split();
subscription::subscribe(&mut write, "book.BTC-PERPETUAL.100ms")
.await
.unwrap();
tokio::spawn(websocket::listener(
read,
messages_received.clone(),
shutdown_signal.subscribe(),
done.clone(),
));
}
In the for loop, I spawn an arbitrary amount of websocket::listener
, that will shutdown when receiving the shutdown_signal
and let main
know when they're done through done
.
When I try to extract this code to a function, like so:
...
for _i in 0..num_websockets {
subscribe_and_listen(messages_received.clone(), shutdown_signal.subscribe(), done.clone());
}
...
async fn subscribe_and_listen(messages_received: Arc<Mutex<i32>>,
shutdown_signal: broadcast::Receiver<&str>,
done: mpsc::Sender<&str>) {
let (ws_stream, _) = websocket::connect().await.unwrap();
let (mut write, read) = ws_stream.split();
subscription::subscribe(&mut write, "book.BTC-PERPETUAL.100ms")
.await
.unwrap();
tokio::spawn(
websocket::listener(
read,
messages_received.clone(),
shutdown_signal,
done.clone(),
)
);
}
The compiler tells me:
error[E0759]: `shutdown_signal` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> src/benchmark.rs:21:9
|
13 | shutdown_signal: broadcast::Receiver<&str>,
| ------------------------- this data with an anonymous lifetime `'_`...
...
21 | / websocket::listener(
22 | | read,
23 | | messages_received.clone(),
24 | | shutdown_signal,
| | --------------- ...is used here...
25 | | done.clone(),
26 | | )
| |_________^
|
note: ...and is required to live as long as `'static` here
--> src/benchmark.rs:20:5
|
20 | tokio::spawn(
| ^^^^^^^^^^^^
note: `'static` lifetime requirement introduced by this bound
--> /Users/b0nes/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.20.0/src/task/spawn.rs:127:28
|
127 | T: Future + Send + 'static,
I have tried many things, but I simply cannot move this bit of code to a function, and I really want to understand how to do this. It seems to me that there is no need for anything to be 'static
, as the function can take full ownership over the results of shutdown_signal.subscribe()
and done.clone()
The solution is to use a String
for the channels shutdown_signal
and done
, or some other type that satisfies 'static, such as a &'static str.
In my case I didn't actually need to provide any strings so I just made a channel with ()
.
The problem was, &str
cannot be owned, but that is exactly what the tokio::spawn
task requires.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.