The standard mechanism to run a background task is to use
IHostedService
. The standard activation mechanism is that
each hosted service starts up sequentially - one at a time. This can take some
time if there are many services and/or if any of them are slow.
This library supplies some extensions to support:
- Starting hosted services in parallel, sequentially, or in an hierarchy.
- A pattern to share generated configuration information that is supplied from a hosted service.
- Helper for docker based hosted services.
The target use cases for this are "modular monoliths" or local "development servers" that run multiple services. Consider combining with LittleForker if the hosted services are wrappers for other long running executables.
Using standard mechanism, these services will be started one after the other:
var hostBuilder = new HostBuilder()
.ConfigureServices(services =>
{
services.AddHostedService<Foo>();
services.AddHostedService<Bar>();
services.AddHostedService<Baz>();
})
With this library, these services are started in parallel and thus potentially faster overall on a multi-core system:
services.AddParallelHostedServices("webapps", w => w
.Host<Foo>()
.Host<Bar>()
.Host<Baz>());
Some services will depend on other services so it's possible to explicitly
specify a sequential set. Here, the API
hosted service depends on
connection string generated by the MySql
hosted service so we start that
first:
services.AddSequentialHostedServices("root", r => r
.Host<MySql>()
.Host<ApiWebApp>());
It is possible to combine sequential and parallel hosted services in a hierarchy to get the optimum balance between start up performance and dependency chain:
services.AddSequentialHostedServices("root", r => r
.HostParallel("containers", // the name is used for logging.
p => p
.Host<LocalStack>()
.Host<MySql>()));
.HostParallel("web-apps",
p => p
.Host<AdminWebApp>()
.Host<ApiWebApp>());
See example project that is fully runnable.
Portions and concepts originally produced with LykkeCorp under MIT Licence.