start method
Start the program.
- HostLifetime.waitForStart
- Services.getService{StartupValidator}().validate()
- HostedLifecycleService.starting
- HostedService.start
- HostedLifecycleService.started
- HostApplicationLifetime.applicationStarted
Implementation
Future<void> start([
CancellationToken? cancellationToken,
]) async {
_logger.starting();
cancellationToken ??= CancellationToken.none;
final cts = CancellationTokenSource.createLinkedTokenSource(
[
cancellationToken,
_applicationLifetime.applicationStopping,
],
);
// Apply startup timeout if configured
if (_options.startupTimeout != null) {
cts.cancelAfter(_options.startupTimeout!);
}
final cancellationToken0 = cts.token;
await _hostLifetime.waitForStart(cancellationToken0);
cancellationToken0.throwIfCancellationRequested();
var exceptions = <Exception>[];
_hostedServices ??= services.getServices<HostedService>();
_hostedLifecycleServices = getHostLifecycles(_hostedServices!);
_hostStarting = true;
var concurrent = _options.servicesStartConcurrently;
var abortOnFirstException = !concurrent;
void logAndRethrow() {
if (exceptions.isNotEmpty) {
if (exceptions.length == 1) {
// Rethrow if it's a single error
var singleException = exceptions[0];
_logger.hostedServiceStartupFaulted(singleException);
throw singleException;
} else {
var ex = AggregateException(
message: 'One or more hosted services failed to start.',
innerExceptions: exceptions,
);
_logger.hostedServiceStartupFaulted(ex);
throw ex;
}
}
}
var validator = services.getService<StartupValidator>();
if (validator != null) {
try {
validator.validate();
} on Exception catch (ex) {
exceptions.add(ex);
// Validation errors cause startup to be aborted.
logAndRethrow();
}
}
// Call starting().
if (_hostedLifecycleServices != null) {
await foreachService<HostedLifecycleService>(
_hostedLifecycleServices!,
cancellationToken,
concurrent,
abortOnFirstException,
exceptions,
(service, token) => service.starting(token),
);
// Exceptions in starting cause startup to be aborted.
logAndRethrow();
}
// Call start().
await foreachService<HostedService>(
_hostedServices!,
cancellationToken,
concurrent,
abortOnFirstException,
exceptions,
(service, token) async {
await service.start(token);
if (service is BackgroundService) {
await _tryExecuteBackgroundService(service);
}
},
);
// Exceptions in start cause startup to be aborted
logAndRethrow();
// Call started
if (_hostedLifecycleServices != null) {
await foreachService<HostedLifecycleService>(
_hostedLifecycleServices!,
cancellationToken,
concurrent,
abortOnFirstException,
exceptions,
(service, token) => service.started(token),
);
}
// Fire HostApplicationLifetime.started
// This catches all exceptions and does not re-throw.
_applicationLifetime.notifyStarted();
_logger.started();
}