reactive_graph_runtime_service_impl/command/
shutdown.rs1use std::ops::Deref;
2use std::sync::Arc;
3use std::sync::atomic::AtomicBool;
4use std::sync::atomic::Ordering;
5use std::time;
6
7use serde_json::json;
8use tokio::task;
9
10use reactive_graph_command_model::CommandArgs;
11use reactive_graph_command_model::entity::Command;
12use reactive_graph_command_model::entity::CommandArg;
13use reactive_graph_graph::PropertyInstanceGetter;
14use reactive_graph_reactive_model_impl::ReactiveEntity;
15use reactive_graph_runtime_model::ENTITY_TYPE_SHUTDOWN;
16use reactive_graph_runtime_model::ShutdownProperties::DELAY;
17use reactive_graph_runtime_service_api::UUID_SHUTDOWN;
18
19pub(crate) fn shutdown_command(shutdown_state: Arc<AtomicBool>) -> Command {
20 let args = CommandArgs::new().arg(
21 CommandArg::new(DELAY)
22 .short('d')
23 .long("delay")
24 .help("Delay shutdown by N seconds")
25 .required(false),
26 );
27 let executor = Box::new(move |e: &ReactiveEntity| {
28 let delay = e.as_u64(DELAY).unwrap_or(0);
29 if delay > 0 {
30 let shutdown_in_seconds = time::Duration::from_secs(delay);
31 let shutdown_state_deferred = shutdown_state.clone();
32 task::spawn(async move {
33 tokio::time::sleep(shutdown_in_seconds).await;
34 shutdown_state_deferred.store(true, Ordering::Relaxed);
35 });
38 json!(delay)
39 } else {
40 shutdown_state.store(true, Ordering::Relaxed);
41 json!(true)
44 }
45 });
46 Command::builder()
47 .ty(ENTITY_TYPE_SHUTDOWN.deref())
48 .id(UUID_SHUTDOWN)
49 .namespace("core")
50 .name("shutdown")
51 .description("Shutdown the application")
52 .help("Shutdown the application")
53 .arguments(args)
54 .executor(executor)
55 .build()
56}