soph_core/traits/
service.rs1use crate::{support::app, traits::ApplicationTrait, Result};
2use async_trait::async_trait;
3
4#[async_trait]
5pub trait ServiceTrait: 'static {
6 type Item;
7
8 fn new() -> Self;
9
10 fn register(self, item: Self::Item) -> Self;
11
12 fn init<A: ApplicationTrait>() -> Self;
13
14 async fn run(self) -> Result<()>;
15
16 async fn shutdown() {
17 let ctrl_c = async {
18 tokio::signal::ctrl_c().await.expect("failed to install Ctrl+C handler");
19 };
20
21 #[cfg(unix)]
22 let terminate = async {
23 tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())
24 .expect("fail to install the terminate signal handler")
25 .recv()
26 .await;
27 };
28
29 #[cfg(not(unix))]
30 let terminate = std::future::pending::<()>();
31
32 tokio::select! {
33 _ = ctrl_c => {},
34 _ = terminate => {},
35 }
36
37 tracing::warn!("signal received, starting graceful shutdown");
38
39 app()
40 .cleanup()
41 .unwrap_or_else(|err| tracing::error!(err = ?err, "failed to clean container"))
42 }
43}