run method
Runs body in the background, tracked so shutdown waits for it.
Returns whether it was accepted. A registry that is draining refuses, so a task started during shutdown is not begun and then abandoned — better to know it never ran than to half-run it.
name appears in the error report when body throws. A task that fails
anonymously at three in the morning is one nobody can place.
Implementation
bool run(String name, Future<void> Function() body) {
if (_closed) return false;
late final Future<void> task;
// Detached from the request's span. A zone value is inherited by whatever is
// spawned inside it, and the request's span ends when the response goes out
// — so a task that kept it would write attributes onto a finished, already
// exported span. Work that wants a trace should start its own.
task = CurrentSpan.runDetached(() => Future<void>.sync(body)).then(
(_) {},
onError: (Object error, StackTrace stack) {
// Swallowed here rather than escaping into the zone, where an unhandled
// asynchronous error takes the isolate down with it.
final report = _onError ?? ServerErrors.report;
report(_TaskFailed(name, error), stack);
},
).whenComplete(() {
_running.remove(task);
if (_running.isEmpty) {
_idle?.complete();
_idle = null;
}
});
_running.add(task);
return true;
}