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()
.
In any case, I didn't explicitly make anything 'static in the for loop example, which works.