mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-15 09:22:55 +00:00
With this commit one can request compute reconfiguration
from the running `compute_ctl` with compute in `Running` state
by sending a new spec:
```shell
curl -d "{\"spec\": $(cat ./compute-spec-new.json)}" http://localhost:3080/configure
```
Internally, we start a separate configurator thread that is waiting on
`Condvar` for `ConfigurationPending` compute state in a loop. Then it does
reconfiguration, sets compute back to `Running` state and notifies other
waiters.
It will need some follow-ups, e.g. for retry logic for control-plane
requests, but should be useful for testing in the current state. This
shouldn't affect any existing environment, since computes are configured
in a different way there.
Resolves neondatabase/cloud#4433
55 lines
1.7 KiB
Rust
55 lines
1.7 KiB
Rust
use std::sync::Arc;
|
|
use std::thread;
|
|
|
|
use anyhow::Result;
|
|
use tracing::{error, info, instrument};
|
|
|
|
use compute_api::responses::ComputeStatus;
|
|
|
|
use crate::compute::ComputeNode;
|
|
|
|
#[instrument(skip(compute))]
|
|
fn configurator_main_loop(compute: &Arc<ComputeNode>) {
|
|
info!("waiting for reconfiguration requests");
|
|
loop {
|
|
let state = compute.state.lock().unwrap();
|
|
let mut state = compute.state_changed.wait(state).unwrap();
|
|
|
|
if state.status == ComputeStatus::ConfigurationPending {
|
|
info!("got configuration request");
|
|
state.status = ComputeStatus::Configuration;
|
|
compute.state_changed.notify_all();
|
|
drop(state);
|
|
|
|
let mut new_status = ComputeStatus::Failed;
|
|
if let Err(e) = compute.reconfigure() {
|
|
error!("could not configure compute node: {}", e);
|
|
} else {
|
|
new_status = ComputeStatus::Running;
|
|
info!("compute node configured");
|
|
}
|
|
|
|
// XXX: used to test that API is blocking
|
|
// std::thread::sleep(std::time::Duration::from_millis(10000));
|
|
|
|
compute.set_status(new_status);
|
|
} else if state.status == ComputeStatus::Failed {
|
|
info!("compute node is now in Failed state, exiting");
|
|
break;
|
|
} else {
|
|
info!("woken up for compute status: {:?}, sleeping", state.status);
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn launch_configurator(compute: &Arc<ComputeNode>) -> Result<thread::JoinHandle<()>> {
|
|
let compute = Arc::clone(compute);
|
|
|
|
Ok(thread::Builder::new()
|
|
.name("compute-configurator".into())
|
|
.spawn(move || {
|
|
configurator_main_loop(&compute);
|
|
info!("configurator thread is exited");
|
|
})?)
|
|
}
|