import 'dart:async'; import 'dart:collection'; typedef ReminderColdStartReplayTask = Future Function(); typedef ReminderColdStartTaskErrorHandler = void Function(Object error, StackTrace stackTrace); class ReminderColdStartQueue { final Queue _tasks = Queue(); final ReminderColdStartTaskErrorHandler? _onTaskError; Future? _inFlightReplay; ReminderColdStartQueue({ReminderColdStartTaskErrorHandler? onTaskError}) : _onTaskError = onTaskError; void enqueue(ReminderColdStartReplayTask task) { _tasks.add(task); } Future replay() { final inFlightReplay = _inFlightReplay; if (inFlightReplay != null) { return inFlightReplay; } final replayCompleter = Completer(); final replayFuture = replayCompleter.future; _inFlightReplay = replayFuture; scheduleMicrotask(() async { try { await _replayInternal(); replayCompleter.complete(); } catch (error, stackTrace) { replayCompleter.completeError(error, stackTrace); } finally { if (identical(_inFlightReplay, replayFuture)) { _inFlightReplay = null; } } }); return replayFuture; } Future _replayInternal() async { while (_tasks.isNotEmpty) { final task = _tasks.removeFirst(); try { await task(); } catch (error, stackTrace) { _onTaskError?.call(error, stackTrace); } } } }