stop method

  1. @override
Future<void> stop({
  1. Duration? timeout,
})
override

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;
}