mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 10:21:52 +00:00
* add restart button to service show page and restart rpc api * Feature/restart rpc (#1555) * add restart rpc and status * wire up rpc * add restarting bool Co-authored-by: Aiden McClelland <me@drbonez.dev> * check if service is restarting * filter package when restarting to avoid glitch Co-authored-by: Aiden McClelland <me@drbonez.dev>
114 lines
3.7 KiB
Rust
114 lines
3.7 KiB
Rust
use std::collections::BTreeMap;
|
|
use std::convert::TryInto;
|
|
use std::sync::atomic::Ordering;
|
|
use std::time::Duration;
|
|
|
|
use chrono::Utc;
|
|
|
|
use super::{pause, resume, start, stop, ManagerSharedState, Status};
|
|
use crate::status::MainStatus;
|
|
use crate::Error;
|
|
|
|
/// Allocates a db handle. DO NOT CALL with a db handle already in scope
|
|
async fn synchronize_once(shared: &ManagerSharedState) -> Result<Status, Error> {
|
|
let mut db = shared.ctx.db.handle();
|
|
let mut status = crate::db::DatabaseModel::new()
|
|
.package_data()
|
|
.idx_model(&shared.manifest.id)
|
|
.expect(&mut db)
|
|
.await?
|
|
.installed()
|
|
.expect(&mut db)
|
|
.await?
|
|
.status()
|
|
.main()
|
|
.get_mut(&mut db)
|
|
.await?;
|
|
let manager_status = shared.status.load(Ordering::SeqCst).try_into().unwrap();
|
|
match manager_status {
|
|
Status::Stopped => match &mut *status {
|
|
MainStatus::Stopped => (),
|
|
MainStatus::Stopping => {
|
|
*status = MainStatus::Stopped;
|
|
}
|
|
MainStatus::Restarting => {
|
|
*status = MainStatus::Starting { restarting: true };
|
|
}
|
|
MainStatus::Starting { .. } => {
|
|
start(shared).await?;
|
|
}
|
|
MainStatus::Running { started, .. } => {
|
|
*started = Utc::now();
|
|
start(shared).await?;
|
|
}
|
|
MainStatus::BackingUp { .. } => (),
|
|
},
|
|
Status::Starting => match *status {
|
|
MainStatus::Stopped | MainStatus::Stopping | MainStatus::Restarting => {
|
|
stop(shared).await?;
|
|
}
|
|
MainStatus::Starting { .. } | MainStatus::Running { .. } => (),
|
|
MainStatus::BackingUp { .. } => {
|
|
pause(shared).await?;
|
|
}
|
|
},
|
|
Status::Running => match *status {
|
|
MainStatus::Stopped | MainStatus::Stopping | MainStatus::Restarting => {
|
|
stop(shared).await?;
|
|
}
|
|
MainStatus::Starting { .. } => {
|
|
*status = MainStatus::Running {
|
|
started: Utc::now(),
|
|
health: BTreeMap::new(),
|
|
};
|
|
}
|
|
MainStatus::Running { .. } => (),
|
|
MainStatus::BackingUp { .. } => {
|
|
pause(shared).await?;
|
|
}
|
|
},
|
|
Status::Paused => match *status {
|
|
MainStatus::Stopped | MainStatus::Stopping | MainStatus::Restarting => {
|
|
stop(shared).await?;
|
|
}
|
|
MainStatus::Starting { .. } | MainStatus::Running { .. } => {
|
|
resume(shared).await?;
|
|
}
|
|
MainStatus::BackingUp { .. } => (),
|
|
},
|
|
Status::Shutdown => (),
|
|
}
|
|
status.save(&mut db).await?;
|
|
Ok(manager_status)
|
|
}
|
|
|
|
pub async fn synchronizer(shared: &ManagerSharedState) {
|
|
loop {
|
|
tokio::select! {
|
|
_ = tokio::time::sleep(Duration::from_secs(5)) => (),
|
|
_ = shared.synchronize_now.notified() => (),
|
|
}
|
|
let status = match synchronize_once(shared).await {
|
|
Err(e) => {
|
|
tracing::error!(
|
|
"Synchronizer for {}@{} failed: {}",
|
|
shared.manifest.id,
|
|
shared.manifest.version,
|
|
e
|
|
);
|
|
tracing::debug!("{:?}", e);
|
|
continue;
|
|
}
|
|
Ok(status) => status,
|
|
};
|
|
tracing::trace!("{} status synchronized", shared.manifest.id);
|
|
shared.synchronized.notify_waiters();
|
|
match status {
|
|
Status::Shutdown => {
|
|
break;
|
|
}
|
|
_ => (),
|
|
}
|
|
}
|
|
}
|