shutdown function

Future shutdown({
  1. ShutdownType? type,
  2. int? exitCode,
  3. Duration handlerTimeout = const Duration(seconds: 30),
  4. Duration overallTimeout = const Duration(minutes: 5),
  5. bool? reverse,
})

Executes the registered handler in (a) increasing priority order (unspecified priorities go to the end) and if that matches (b) in the order they were added.

Implementation

Future shutdown({
  ShutdownType? type,
  int? exitCode,
  Duration handlerTimeout = const Duration(seconds: 30),
  Duration overallTimeout = const Duration(minutes: 5),
  bool? reverse,
}) async {
  type ??= ShutdownType.vm;
  reverse ??= false;

  if (_shutdownStarted) return;
  _shutdownStarted = true;

  Timer(overallTimeout, () {
    _kill(type, exitCode);
  });

  _signalSubscriptions.forEach((subs) => subs.cancel());

  _entries.sort();
  final entries = reverse ? _entries.reversed.toList() : _entries;

  for (final entry in entries) {
    try {
      final f = entry._handler();
      if (f is Future) {
        await f.timeout(entry._timeout ?? handlerTimeout,
            onTimeout: () => null);
      } else {
        await f;
      }
    } catch (e, st) {
      // TODO: error reporting with logging
      stderr.writeln('Shutdown handler error: $e\nStacktrace:\n$st');
    }
  }

  _kill(type, exitCode);
}