Line data Source code
1 : use std::sync::Arc;
2 : use std::thread;
3 :
4 : use tracing::{error, info, instrument};
5 :
6 : use compute_api::responses::ComputeStatus;
7 :
8 : use crate::compute::ComputeNode;
9 :
10 0 : #[instrument(skip_all)]
11 : fn configurator_main_loop(compute: &Arc<ComputeNode>) {
12 : info!("waiting for reconfiguration requests");
13 : loop {
14 : let mut state = compute.state.lock().unwrap();
15 :
16 : // We have to re-check the status after re-acquiring the lock because it could be that
17 : // the status has changed while we were waiting for the lock, and we might not need to
18 : // wait on the condition variable. Otherwise, we might end up in some soft-/deadlock, i.e.
19 : // we are waiting for a condition variable that will never be signaled.
20 : if state.status != ComputeStatus::ConfigurationPending {
21 : state = compute.state_changed.wait(state).unwrap();
22 : }
23 :
24 : // Re-check the status after waking up
25 : if state.status == ComputeStatus::ConfigurationPending {
26 : info!("got configuration request");
27 : state.set_status(ComputeStatus::Configuration, &compute.state_changed);
28 : drop(state);
29 :
30 : let mut new_status = ComputeStatus::Failed;
31 : if let Err(e) = compute.reconfigure() {
32 : error!("could not configure compute node: {}", e);
33 : } else {
34 : new_status = ComputeStatus::Running;
35 : info!("compute node configured");
36 : }
37 :
38 : // XXX: used to test that API is blocking
39 : // std::thread::sleep(std::time::Duration::from_millis(10000));
40 :
41 : compute.set_status(new_status);
42 : } else if state.status == ComputeStatus::Failed {
43 : info!("compute node is now in Failed state, exiting");
44 : break;
45 : } else {
46 : info!("woken up for compute status: {:?}, sleeping", state.status);
47 : }
48 : }
49 : }
50 :
51 0 : pub fn launch_configurator(compute: &Arc<ComputeNode>) -> thread::JoinHandle<()> {
52 0 : let compute = Arc::clone(compute);
53 0 :
54 0 : thread::Builder::new()
55 0 : .name("compute-configurator".into())
56 0 : .spawn(move || {
57 0 : configurator_main_loop(&compute);
58 0 : info!("configurator thread is exited");
59 0 : })
60 0 : .expect("cannot launch configurator thread")
61 0 : }
|