Struct spirit::Spirit

source ·
pub struct Spirit<O = Empty, C = Empty> { /* private fields */ }
Expand description

The main manipulation handle/struct of the library.

This gives access to the runtime control over the behaviour of the spirit library and allows accessing current configuration and manipulate the behaviour to some extent.

Note that the functionality of the library is not disturbed by dropping this, you simply lose the ability to control the library.

By creating this (with the build pattern), you start a background thread that keeps track of signals, reloading configuration and other bookkeeping work.

The passed callbacks are run in the service threads if they are caused by the signals. They, however, can be run in any other thread when the controlled actions are invoked manually.

This is supposed to be a singleton (it is not enforced, but having more of them around is probably not what you want).

Warning

Only one callback is allowed to run at any given time. This makes it easier to write the callbacks (eg. transitioning between configurations at runtime), but if you ever invoke a method that contains callbacks from within a callback, you’ll get a deadlock.

Examples

use spirit::{Empty, Spirit};

Spirit::<Empty, Empty>::new()
    .on_config(|_opts, _new_cfg| {
        // Adapt to new config here
    })
    .run(|_spirit| {
        // Application runs here
        Ok(())
    });

Implementations§

A constructor with default initial config.

Before the application successfully loads the first config, there still needs to be something (passed, for example, to validation callbacks) This puts the default value in there.

Similar to new, but with specific initial config value

Access the parsed command line.

This gives the access to the type declared when creating Spirit. The content doesn’t change (the command line is parsed just once) and it does not contain the options added by Spirit itself.

Access to the current configuration.

This returns the current version of configuration. Note that you can keep hold of this snapshot of configuration (which does not change), but calling this again might give a different config.

If you do want to hold onto the returned configuration for longer time, upgrade the returned Lease to Arc.

Examples
extern crate arc_swap;
extern crate spirit;

use arc_swap::Lease;
use spirit::{Empty, Spirit};

let (spirit, _, _) = Spirit::<Empty, Empty>::new()
    .build(false)
    .unwrap();

let old_config = Lease::upgrade(&spirit.config());
Notes

If created with the with_config_storage, the current configuration is also available through that storage. This allows, for example, having the configuration in a global variable, for example.

Force reload of configuration.

The configuration gets reloaded either when the process receives SIGHUP or when this method is called manually.

This is what happens:

  • The configuration is loaded from all places.
  • Validation callbacks are called (all of them).
  • If no validation callback returns an error, success callbacks of the validation results are called. Otherwise, abort callbacks are called.
  • Logging is reopened in the new form.
  • The configuration is published into the storage.
  • The on_config callbacks are called.

If any step fails, it is aborted and the old configuration is preserved.

Warning

The Spirit allows to run only one callback at a time (even from multiple threads), to make reasoning about configuration transitions and such easier (and to make sure the callbacks don’t have to by Sync). That, however, means that you can’t call config_reload or terminate from any callback (that would lead to a deadlock).

Is the application in the shutdown phase?

This can be used if the daemon does some kind of periodic work, every loop it can check if the application should shut down.

The other option is to hook into on_terminate and shut things down (like drop some futures and make the tokio event loop empty).

Examples
use std::thread;
use std::time::Duration;

use spirit::{Empty, Spirit};

let (spirit, _, _) = Spirit::<Empty, Empty>::new()
    .build(false)
    .unwrap();

while !spirit.is_terminated() {
    thread::sleep(Duration::from_millis(100));
}

Terminate the application in a graceful manner.

The Spirit/application can be terminated either by one of termination signals (SIGTERM, SIGQUIT, SIGINT) or by manually calling this method.

The termination does this:

  • Calls the on_terminate callbacks.
  • Sets the is_terminated flag is set.
  • Drops all callbacks from spirit. This allows destruction/termination of parts of program by dropping remote handles or similar things.
  • The background thread terminates.
Warning

The Spirit guarantees only one callback runs at a time. That means you can’t call this from within a callback (it would lead to deadlock).

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

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

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.