Tokio restart failed task

I have a number of forever-running tasks that I'd like to be able to restart on failure. For example, in the following example, I start two "workers". These should run forever, and if they fail, I'd like to be able to restart them.

async fn worker(worker_id: &str)  {
  loop {
    let res = reqwest::get(...).await.unwrap();
    // process response

async fn main() {
  tokio::spawn(async { worker("wrk1").await; });
  tokio::spawn(async { worker("wrk2").await; });

  // start webserver

For now I'm just unwrapping any possible error and using using panic = 'abort' to kill the entire app and have it restarted, but I'm wondering if there's a delicate approach?

You can spawn an extra task for managing and restarting it.

Is using futures::future::select_all the right tool for that? I came up with something like this (I'll need to use idx to figure out which worker to restart)

async fn supervisor() {
	let w1 = tokio::spawn(async { worker("wrk1").await; });
	let w2 = tokio::spawn(async { worker("wrk2").await; });

	let mut workers = vec![w1, w2];
	loop {
		let supervisor = futures::future::select_all(workers);
		workers = match supervisor.await {
			(Err(_), _idx, mut workers) => {
				let restarted = tokio::spawn(async { worker("wrk1").await; });
			(Ok(_), _, _) => {
				// TODO: should not happen, just return an empty vec for now

I would not use select_all. Just spawn a separate manager per task you want to manage.