stop method

Future<void> stop({
  1. Duration? drainTimeout,
})

Closes every endpoint, optionally letting in-flight calls finish first.

With drainTimeout null every endpoint closes at once and a running call fails with UNAVAILABLE. With a budget the endpoints stop admitting new calls, and their running ones get up to the budget to finish.

Implementation

Future<void> stop({Duration? drainTimeout}) async {
  if (drainTimeout != null) {
    for (final endpoint in _live.keys) {
      // markDraining, not drain(): the latter cancels every active context,
      // the opposite of letting in-flight calls finish.
      endpoint.markDraining();
    }
    await drainUntilIdle(
      pending: () => inFlightResponderCalls(_live.keys),
      budget: drainTimeout,
      logger: _log,
    );
  }
  // Concurrently: each close may wait on its own peer, and one dead
  // connection must not delay the rest. Caught per endpoint, because
  // Future.wait abandons the remaining futures on the first error.
  await Future.wait([
    for (final endpoint in List.of(_live.keys))
      endpoint.close().catchError((Object e) {
        _log.warning('Error closing an endpoint: $e');
      }),
  ]);
  for (final endpoint in List.of(_live.keys)) {
    release(endpoint);
  }
}