58 lines
1.5 KiB
Dart
58 lines
1.5 KiB
Dart
import 'dart:async';
|
|
import 'dart:collection';
|
|
|
|
typedef ReminderColdStartReplayTask = Future<void> Function();
|
|
typedef ReminderColdStartTaskErrorHandler =
|
|
void Function(Object error, StackTrace stackTrace);
|
|
|
|
class ReminderColdStartQueue {
|
|
final Queue<ReminderColdStartReplayTask> _tasks =
|
|
Queue<ReminderColdStartReplayTask>();
|
|
final ReminderColdStartTaskErrorHandler? _onTaskError;
|
|
Future<void>? _inFlightReplay;
|
|
|
|
ReminderColdStartQueue({ReminderColdStartTaskErrorHandler? onTaskError})
|
|
: _onTaskError = onTaskError;
|
|
|
|
void enqueue(ReminderColdStartReplayTask task) {
|
|
_tasks.add(task);
|
|
}
|
|
|
|
Future<void> replay() {
|
|
final inFlightReplay = _inFlightReplay;
|
|
if (inFlightReplay != null) {
|
|
return inFlightReplay;
|
|
}
|
|
|
|
final replayCompleter = Completer<void>();
|
|
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<void> _replayInternal() async {
|
|
while (_tasks.isNotEmpty) {
|
|
final task = _tasks.removeFirst();
|
|
try {
|
|
await task();
|
|
} catch (error, stackTrace) {
|
|
_onTaskError?.call(error, stackTrace);
|
|
}
|
|
}
|
|
}
|
|
}
|