close method
Stops accepting, then waits for the requests already accepted.
When a BackgroundTasks was passed to serve, its work is drained
too, and within the same drain budget rather than a second one — the
platform kills the process on its own schedule, and two budgets in series
exceed it.
Returns true when everything finished within drain, and false when
the deadline passed with work still running, at which point the caller
decides whether to wait longer or exit anyway.
Implementation
Future<bool> close({Duration drain = const Duration(seconds: 30)}) async {
await _server.close();
final deadline = Stopwatch()..start();
final requestsSettled = await _inFlight.settled(drain);
final background = _background;
var tasksSettled = true;
if (background != null) {
// Whatever is left of the budget. A request that used all of it leaves
// nothing, and `close` reports the failure rather than waiting twice as
// long as it was told to.
final remaining = drain - deadline.elapsed;
tasksSettled = await background.close(
within: remaining.isNegative ? Duration.zero : remaining,
);
}
// After the tasks, because a background task may still be using whatever a
// layer owns. Always, because a server with no background work still has
// layers to release — an early return here left them open.
await _disposeLayers();
return requestsSettled && tasksSettled;
}