soph_core/traits/
service.rs

1use 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}