start static method
Future<Runtime>
start(
- Module module, {
- ResolverBackend? backend,
- CleanupFailureObserver? cleanupFailureObserver,
- Iterable<
RuntimeObserver> observers = const <RuntimeObserver>[], - RuntimeObserverErrorHandler? observerErrorHandler,
Build a runtime, install constructor bindings, and acquire resources.
Implementation
static Future<Runtime> start(
Module module, {
ResolverBackend? backend,
CleanupFailureObserver? cleanupFailureObserver,
Iterable<RuntimeObserver> observers = const <RuntimeObserver>[],
RuntimeObserverErrorHandler? observerErrorHandler,
}) async {
final observerHub = _RuntimeObservers.create(
observers,
observerErrorHandler,
);
final resolver = backend ?? AutoInjectorBackend();
final rootScope = Scope._();
final rootObservation = observerHub == null
? null
: _ExecutionObservation(
observers: observerHub,
executionId: 0,
executionLabel: null,
parentExecutionId: null,
startedAt: DateTime.now(),
initialMetadata: const <String, Object>{},
);
final context = _RuntimeContext(
backend: resolver,
scope: rootScope,
cancellation: CancellationSignal._(),
overrides: const <_ServiceIdentity, Object>{},
locals: const <Object, Object>{},
observation: rootObservation,
);
try {
for (final binding in module) {
if (!binding._isResource) {
binding._register(resolver);
}
}
resolver.commit();
for (final binding in module) {
if (binding._isResource) {
await binding._startResource(context);
}
}
await Future<void>.sync(resolver.activate);
return Runtime._(context, cleanupFailureObserver, observerHub);
} catch (error, stackTrace) {
final outcome = ExitDefect<Object, Object>(error, stackTrace);
Object? cleanupError;
StackTrace? cleanupStackTrace;
try {
await rootScope._close(outcome);
} catch (releaseError, releaseStack) {
final diagnostic = CleanupFailureDiagnostic(
outcome: outcome,
error: _asScopeReleaseException(releaseError, releaseStack),
executionId: 0,
);
_emitCleanupFailure(rootObservation, rootScope, diagnostic);
await _notifyCleanupFailureBestEffort(
cleanupFailureObserver,
diagnostic,
);
cleanupError = releaseError;
cleanupStackTrace = releaseStack;
}
try {
await Future<void>.sync(resolver.close);
} catch (backendError, backendStackTrace) {
if (cleanupError == null) {
cleanupError = backendError;
cleanupStackTrace = backendStackTrace;
} else {
cleanupError = CompositeDefect(
primary: cleanupError,
primaryStackTrace: cleanupStackTrace!,
secondary: backendError,
secondaryStackTrace: backendStackTrace,
);
cleanupStackTrace = backendStackTrace;
}
}
if (cleanupError != null) {
Error.throwWithStackTrace(
CompositeDefect(
primary: error,
primaryStackTrace: stackTrace,
secondary: cleanupError,
secondaryStackTrace: cleanupStackTrace!,
),
stackTrace,
);
}
Error.throwWithStackTrace(error, stackTrace);
}
}