sdk tweaks (#2760)

* sdk tweaks

* update action result types

* accommodate new action response types

* fix: show action value labels

* Feature/get status effect (#2765)

* wip: get status

* feat: Add the get_status for effects

* feat: Do a callback

---------

Co-authored-by: J H <dragondef@gmail.com>

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
Co-authored-by: waterplea <alexander@inkin.ru>
Co-authored-by: J H <dragondef@gmail.com>
This commit is contained in:
Aiden McClelland
2024-10-28 12:12:36 -06:00
committed by GitHub
parent 42cfd69463
commit 26ae0bf207
28 changed files with 871 additions and 456 deletions

View File

@@ -36,6 +36,7 @@ struct ServiceCallbackMap {
(NonDetachingJoinHandle<()>, Vec<CallbackHandler>),
>,
get_store: BTreeMap<PackageId, BTreeMap<JsonPointer, Vec<CallbackHandler>>>,
get_status: BTreeMap<PackageId, Vec<CallbackHandler>>,
}
impl ServiceCallbacks {
@@ -71,6 +72,10 @@ impl ServiceCallbacks {
});
!v.is_empty()
});
this.get_status.retain(|_, v| {
v.retain(|h| h.handle.is_active() && h.seed.strong_count() > 0);
!v.is_empty()
});
})
}
@@ -220,6 +225,20 @@ impl ServiceCallbacks {
.push(handler);
})
}
pub(super) fn add_get_status(&self, package_id: PackageId, handler: CallbackHandler) {
self.mutate(|this| this.get_status.entry(package_id).or_default().push(handler))
}
#[must_use]
pub fn get_status(&self, package_id: &PackageId) -> Option<CallbackHandlers> {
self.mutate(|this| {
if let Some(watched) = this.get_status.remove(package_id) {
Some(CallbackHandlers(watched))
} else {
None
}
.filter(|cb| !cb.0.is_empty())
})
}
pub(super) fn add_get_store(
&self,

View File

@@ -1,9 +1,11 @@
use std::str::FromStr;
use clap::builder::ValueParserFactory;
use models::FromStrParser;
use models::{FromStrParser, PackageId};
use crate::service::effects::prelude::*;
use crate::service::rpc::CallbackId;
use crate::status::MainStatus;
pub async fn restart(
context: EffectContext,
@@ -23,6 +25,46 @@ pub async fn shutdown(
Ok(())
}
#[derive(Debug, Clone, Serialize, Deserialize, TS, Parser)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct GetStatusParams {
#[ts(optional)]
pub package_id: Option<PackageId>,
#[ts(optional)]
#[arg(skip)]
pub callback: Option<CallbackId>,
}
pub async fn get_status(
context: EffectContext,
GetStatusParams {
package_id,
callback,
}: GetStatusParams,
) -> Result<MainStatus, Error> {
let context = context.deref()?;
let id = package_id.unwrap_or_else(|| context.seed.id.clone());
let db = context.seed.ctx.db.peek().await;
let status = db
.as_public()
.as_package_data()
.as_idx(&id)
.or_not_found(&id)?
.as_status()
.de()?;
if let Some(callback) = callback {
let callback = callback.register(&context.seed.persistent_container);
context.seed.ctx.callbacks.add_get_status(
id,
super::callbacks::CallbackHandler::new(&context, callback),
);
}
Ok(status)
}
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]

View File

@@ -50,6 +50,12 @@ pub fn handler<C: Context>() -> ParentHandler<C> {
.no_display()
.with_call_remote::<ContainerCliContext>(),
)
.subcommand(
"get-status",
from_fn_async(control::get_status)
.no_display()
.with_call_remote::<ContainerCliContext>(),
)
// dependency
.subcommand(
"set-dependencies",

View File

@@ -1,6 +1,8 @@
use std::sync::Arc;
use std::time::Duration;
use imbl::vector;
use super::start_stop::StartStop;
use super::ServiceActorSeed;
use crate::prelude::*;
@@ -45,7 +47,8 @@ async fn service_actor_loop(
let id = &seed.id;
let kinds = current.borrow().kinds();
if let Err(e) = async {
seed.ctx
let major_changes_state = seed
.ctx
.db
.mutate(|d| {
if let Some(i) = d.as_public_mut().as_package_data_mut().as_idx_mut(&id) {
@@ -89,11 +92,22 @@ async fn service_actor_loop(
..
} => MainStatus::Stopped,
};
let previous = i.as_status().de()?;
i.as_status_mut().ser(&main_status)?;
return Ok(previous
.major_changes(&main_status)
.then_some((previous, main_status)));
}
Ok(())
Ok(None)
})
.await?;
if let Some((previous, new_state)) = major_changes_state {
if let Some(callbacks) = seed.ctx.callbacks.get_status(id) {
callbacks
.call(vector![to_value(&previous)?, to_value(&new_state)?])
.await?;
}
}
seed.synchronized.notify_waiters();
match kinds {