close method
Stops the server. Without drain it stops now: parked requests get
a 503. With drain it first closes the listener, answers everything
already accepted (each answer says Connection: close) and waits up
to that long for in-flight requests to finish, then stops. Idempotent.
Implementation
Future<void> close({Duration? drain}) async {
if (!_closed.isCompleted) _closed.complete();
if (drain != null) await _runner.drain(drain);
await _runner.close();
// The engine is stopped: helpers have nothing left to answer.
final helpers = _helpers;
_helpers = const [];
for (final helper in helpers) {
await helper.close();
}
}