pub struct Controller;
Expand description

Service to start and gracefully stop the system runtime.

This service offers a static API to wait for a shutdown signal or manually initiate the Relay shutdown. To use this functionality, it first needs to be started with Controller::start.

To shut down gracefully, other services can register with Controller::shutdown_handle. When a shutdown signal is sent to the process, every service will receive a Shutdown message with an optional timeout. To wait for the entire shutdown sequence including the shutdown timeout instead, use finished. It resolves when the shutdown has completed.

§Signals

By default, the controller watches for process signals and converts them into graceful or immediate shutdown messages. These signals are platform-dependent:

  • Unix: SIGINT and SIGQUIT trigger an immediate shutdown, SIGTERM a graceful one.
  • Windows: CTRL-C, CTRL-BREAK, CTRL-CLOSE all trigger an immediate shutdown.

§Example

use relay_system::{Controller, Service, Shutdown, ShutdownMode};
use std::time::Duration;

struct MyService;

impl Service for MyService {
    type Interface = ();

    fn spawn_handler(self, mut rx: relay_system::Receiver<Self::Interface>) {
        tokio::spawn(async move {
            let mut shutdown = Controller::shutdown_handle();

            loop {
                tokio::select! {
                    shutdown = shutdown.notified() => break, // Handle shutdown here
                    Some(message) = rx.recv() => (),         // Process incoming message
                }
            }
        });
    }
}

#[tokio::main(flavor = "current_thread")]
async fn main() {
    // Start the controller near the beginning of application bootstrap. This allows other
    // services to register for shutdown messages.
    Controller::start(Duration::from_millis(10));

    // Start all other services. Controller::shutdown_handle will use the same controller
    // instance and receives the configured shutdown timeout.
    let addr = MyService.start();

    // By triggering a shutdown, all attached services will be notified. This happens
    // automatically when a signal is sent to the process (e.g. SIGINT or SIGTERM).
    Controller::shutdown(ShutdownMode::Graceful);

    // Wait for the system to shut down before winding down the application.
    Controller::shutdown_handle().finished().await;
}

Implementations§

source§

impl Controller

source

pub fn start(shutdown_timeout: Duration)

Starts a controller that monitors shutdown signals.

source

pub fn shutdown(mode: ShutdownMode)

Manually initiates the shutdown process of the system.

source

pub fn shutdown_handle() -> ShutdownHandle

Returns a handle to receive shutdown notifications.

Trait Implementations§

source§

impl Debug for Controller

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more