Module spirit::fragment[][src]

Expand description

Fragments of configuration.

There are several crates that provide common fragments of configuration to configure some specific functionality. These fragments are described in terms of the Fragment trait.

How to use them

A Fragment can be used directly, usually through create method. The trait has some other methods and associated types, but these are usually used only internally.

The other option is to use fragments through Pipelines. A pipeline describes how the fragment is extracted from the configuration, how instances of resources it describes are cached and created, how to post-process them and how to install or activate them. Depending on the kind of fragment, less or more tweaking may be needed or desirable.

How pipelines work

A Pipeline manages certain fragment of configuration and creates Resources out of it. There are several traits in play there.

  • A pipeline is triggered whenever new configuration is loaded. It runs its configured Extractor. This extractor provides an instance of the Fragment.
  • A Driver is provided with the extracted fragment. The Driver decides if the Resource needs to be recreated or if an old instance need to be destroyed. Each fragment has its default Driver, but the driver of a pipeline can be manually replaced by other one, to for example change caching strategy. Note that the Driver is allowed to partition the Fragment into smaller Fragments and drive the rest of the pipeline multiple times on the smaller ones (eg. a Vec<F> would be split into multiple runs over F).
  • When creating the Resource, there are two stages. First, a Seed is created with the make_seed method. Then one or more Resources are made out of the Seed with the make_resource method. This allows more flexible caching strategies and allows for example to change attached configuration without closing and opening a network socket if the port haven’t changed (which would be problematic, as spirit first tries to create the new instance and only if it works gets rid of the old one ‒ but that couldn’t be done if we still had the old with the same port). Some Fragments don’t need this two-stage configuration, therefore they have the Seed set to () and trivial make_seed method. You can use the simple_fragment macro to generate such trait configuration.
  • Then the resource goes through configured set of Transformations. These may be quite arbitrary, but they usually tie the resource with some kind of functionality ‒ a network socket is provided with a function to handle each new connection, a HTTP server is provided with the service it’ll serve, etc. A freshly created Pipeline has no transformations, but they can be added.
  • Finally, the resulting product is installed using the Installer. Some fragments come with a default installer, some do not. The Installer is often set as part of a transformation. Nevertheless, an installer can always be set manually.
  • The installer returns UninstallHandles. These represent the lifetime of the installed resources. The pipeline stores them until the time is right to destroy the resources ‒ then it drops the handles, which results in removal of the resources.

Names

Most methods around the mentioned traits take a name: &'static str parameter. This is used by them to enrich log messages, as there might be multiple distinct parts of configuration of the same type.

The name is provided when creating the Pipeline. It needs to be a string literal, but as this should correspond to specific functionality in the program, this should not be very limiting.

TODO: An example

How to create a fragment

First, try to do it manually, without fragments or pipeline ‒ eg. write the code that takes the configuration and creates something out of it and activates it.

Then decide how this should be reloaded when new configuration appears, how it can be reinstalled or if and how it should be cached.

Then you can have a look at available pieces, like ready-made drivers or installers. Sometimes, they come from another trait ‒ eg. the spirit_tokio crate comes with an installer for futures. Usually, you need to implement only the Fragment trait (either in two-stage or single-stage fashion), but sometimes you might need to add some kind of Transformation to tie the part that comes from the configuration with some actual code.

You may also want to implement the Stackable and possibly Comparable traits for the fragment.

Modules

A collection of Drivers for use by Fragments.

The home of the Pipeline.

Structs

A sequence installer.

Traits

A trait describing something that extracts a fragment from configuration and command line options.

A fragment of configuration.

An entity that is able to install a resource.

A trait similar to Stackable, but marking the ability to be optional.

A trait to mark Fragments that can form collections.

A transformation of resources.