stop method
Stops the server. With server.shutdown=graceful it stops accepting
connections and lets running requests finish for up to timeout
(30 seconds when null), then closes what is left; open event
streams and WebSocket sessions are closed at once.
Implementation
@override
Future<void> stop({Duration? timeout}) async {
final starting = _starting;
_starting = null;
if (starting != null) {
try {
await starting;
} on Object {
// It did not start: nothing to stop.
}
}
final server = _server;
if (server == null) {
return;
}
_server = null;
// No new connections; open event streams and WebSockets end now
// (they would never finish by themselves).
final closing = server.close();
for (final session in _sessions.toList()) {
unawaited(
session
.close(CloseStatus.goingAway.withReason('Server stopping'))
.catchError((Object _) {}),
);
}
for (final exchange in _exchanges.toList()) {
if (exchange.isStreaming) {
unawaited(exchange.abort());
}
}
if (settings.shutdown == Shutdown.graceful) {
final limit = timeout ?? const Duration(seconds: 30);
final active = _exchanges.isNotEmpty;
if (active) {
_log.info('Commencing graceful shutdown. Waiting for active requests');
}
// Running requests finish; then the non-forced close ends idle
// connections once their responses are out (a forced close could
// cut a response the client is still reading).
final completed =
await Future.wait([
for (final exchange in _exchanges) exchange.finished,
])
.then((_) => closing)
.then((_) => true)
.timeout(limit, onTimeout: () => false);
if (active || !completed) {
_log.info(
completed
? 'Graceful shutdown complete'
: 'Graceful shutdown aborted with one or more requests still '
'active',
);
}
if (completed) {
return;
}
}
await server.close(force: true);
await closing;
}