drain method
- int batchSize = 50,
Best-effort: drain pending events into Supabase. Re-entrant guard
via _draining so an online tick that fires while a previous drain
is still in flight is a no-op. Returns the number of events that
successfully replayed.
Implementation
Future<int> drain({int batchSize = 50}) async {
if (!_outbox.isReady) return 0;
if (_draining) return 0;
_draining = true;
try {
final events = _outbox.pendingAndFailed(limit: batchSize);
if (events.isEmpty) return 0;
var succeeded = 0;
for (final ev in events) {
if (!_knownReplayTables.contains(ev.tableName)) {
// Unknown table — leave pending so a future SyncWorker version
// with a handler can pick it up. Don't mark failed; the row
// isn't broken, just unsupported.
continue;
}
_outbox.markSyncing(ev.id);
try {
await _replay(ev);
_outbox.markSynced(ev.id);
succeeded++;
} catch (e) {
_outbox.markFailed(ev.id, e.toString());
dev.log(
'Replay failed for ${ev.tableName}#${ev.id}: $e',
name: 'SyncWorker',
);
}
}
if (succeeded > 0) {
dev.log('Drained $succeeded events.', name: 'SyncWorker');
}
return succeeded;
} finally {
_draining = false;
}
}