clearQueuesOnDisconnect method
Clears all queues when connectivity is lost.
This is the preferred approach since the Queue package doesn't support pause/resume operations. Tasks remain in the sync_queue database and will be restored when connectivity returns.
Implementation
Future<void> clearQueuesOnDisconnect() async {
_log.info('Clearing all request queues due to connectivity loss');
// Clear idempotency key tracking
for (final keys in _activeIdempotencyKeys.values) {
keys.clear();
}
// Use runZonedGuarded to catch any unhandled QueueCancelledException
final List<dynamic> disposalErrors = [];
await runZonedGuarded(() async {
// Dispose and recreate queues
await Future.wait(
_queues.values.map((queue) async {
try {
await queue.dispose();
} catch (e) {
if (e is! QueueCancelledException) {
// Only log non-cancellation exceptions as these are expected
_log.warning('Error disposing queue: $e');
}
// QueueCancelledException is expected when cancelling queues
}
}),
);
}, (error, stack) {
// Capture any unhandled QueueCancelledException
disposalErrors.add(error);
_log.fine('Caught unhandled disposal error: ${error.runtimeType}');
});
// Give time for any async cleanup to complete
await Future.delayed(const Duration(milliseconds: 20));
// Recreate fresh queues
_queues[QueueType.foreground] = RequestQueue(
parallelism: 1,
delay: const Duration(milliseconds: 50),
name: 'ForegroundQueue',
);
_queues[QueueType.load] = RequestQueue(
parallelism: 2,
delay: const Duration(milliseconds: 50),
name: 'LoadQueue',
);
_queues[QueueType.background] = RequestQueue(
parallelism: 1,
delay: const Duration(milliseconds: 100),
name: 'BackgroundQueue',
);
_log.info('All queues cleared and recreated (${disposalErrors.length} '
'disposal errors captured)');
}