Skip to content

Instantly share code, notes, and snippets.

@wpcarro
Created December 23, 2024 05:21
Show Gist options
  • Save wpcarro/f3507778b8dfd0e8d198f4ddab9072e1 to your computer and use it in GitHub Desktop.
Save wpcarro/f3507778b8dfd0e8d198f4ddab9072e1 to your computer and use it in GitHub Desktop.
Thread supervisor with restarts (multiple threads)
#[derive(Debug, Clone, Copy)]
enum ThreadState {
Unstarted,
InProgress,
Panicked,
Success,
}
fn main() {
let mut init = Vec::with_capacity(3);
init.push(ThreadState::Unstarted);
init.push(ThreadState::Unstarted);
init.push(ThreadState::Unstarted);
let x = Arc::new(Mutex::new(init));
let run = |i: usize, f: fn(usize) -> ()| {
let x2 = Arc::clone(&x);
let x3 = Arc::clone(&x);
thread::spawn(move || {
x2.lock().unwrap()[i] = ThreadState::InProgress;
panic::set_hook(Box::new(move |_| {
x2.lock().unwrap()[i] = ThreadState::Panicked;
}));
f(i);
x3.lock().unwrap()[i] = ThreadState::Success;
});
};
let do_work = |i: usize| {
sleep(Duration::from_secs(3));
if *[true, false].choose(&mut thread_rng()).unwrap() {
panic!("Thread ID {i}: Oops");
}
};
for i in 0..3 {
run(i, do_work);
}
let mut done = HashSet::new();
loop {
if done.len() == 3 {
println!("Supervision done. Exiting...");
break;
}
for i in 0..3 {
let thread_state = {
x.lock().unwrap()[i]
};
println!("Thread ID {i}: ({thread_state:?})");
match thread_state {
ThreadState::Panicked => {
x.lock().unwrap()[i] = ThreadState::Unstarted;
run(i, do_work);
}
ThreadState::Success => {
done.insert(i);
}
_ => { }
}
sleep(Duration::from_millis(100));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment