soph_core/traits/
service.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use crate::{support::app, traits::ApplicationTrait, Result};
use async_trait::async_trait;

#[async_trait]
pub trait ServiceTrait: 'static {
    type Item;

    fn new() -> Self;

    fn register(self, item: Self::Item) -> Self;

    fn init<A: ApplicationTrait>() -> Self;

    async fn run(self) -> Result<()>;

    async fn shutdown() {
        let ctrl_c = async {
            tokio::signal::ctrl_c()
                .await
                .expect("failed to install Ctrl+C handler");
        };

        #[cfg(unix)]
        let terminate = async {
            tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())
                .expect("fail to install the terminate signal handler")
                .recv()
                .await;
        };

        #[cfg(not(unix))]
        let terminate = std::future::pending::<()>();

        tokio::select! {
            _ = ctrl_c => {},
            _ = terminate => {},
        }

        tracing::warn!("signal received, starting graceful shutdown");

        app()
            .cleanup()
            .unwrap_or_else(|err| tracing::error!(err = ?err, "failed to clean container"))
    }
}