feat: add historical data
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:drift/drift.dart';
|
||||
@@ -45,6 +46,9 @@ class RemoteSyncService {
|
||||
static const _venueIdKey = 'remote_venue_id';
|
||||
static const _syncStateId = 'default';
|
||||
|
||||
/// Most outbox events sent per sync; a larger backlog drains over syncs.
|
||||
static const maxEventsPerSync = 500;
|
||||
|
||||
static const _pollingInterval = Duration(
|
||||
seconds: kSyncPollingIntervalSeconds,
|
||||
);
|
||||
@@ -227,6 +231,8 @@ class RemoteSyncService {
|
||||
|
||||
Future<void> _doSync(_Credentials credentials) async {
|
||||
final state = await _getSyncState();
|
||||
// Read before the snapshot, so the snapshot is never older than the events
|
||||
final outbox = await _pendingEvents();
|
||||
final openTabs = await barTabService.getOpenTabs();
|
||||
|
||||
final response = await apiClient.sync(
|
||||
@@ -235,9 +241,15 @@ class RemoteSyncService {
|
||||
deviceId: credentials.deviceId,
|
||||
cursor: state?.serverCursor,
|
||||
openTabs: openTabs.map(_toSnapshot).toList(),
|
||||
events: [
|
||||
for (final row in outbox)
|
||||
jsonDecode(row.payload) as Map<String, dynamic>,
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
await _clearSentEvents(response);
|
||||
|
||||
for (final command in response.commands) {
|
||||
await _processCommand(command, credentials);
|
||||
}
|
||||
@@ -251,6 +263,38 @@ class RemoteSyncService {
|
||||
await _updateSyncState(success: true, cursor: response.cursor);
|
||||
}
|
||||
|
||||
Future<List<TabEventRow>> _pendingEvents() {
|
||||
return (database.select(database.tabEvents)
|
||||
..orderBy([
|
||||
(row) => OrderingTerm.asc(row.createdAt),
|
||||
// Same-second events keep their insertion order
|
||||
(row) => OrderingTerm.asc(const CustomExpression<int>('rowid')),
|
||||
])
|
||||
..limit(maxEventsPerSync))
|
||||
.get();
|
||||
}
|
||||
|
||||
/// Events the server stored or refused leave the outbox. Events created
|
||||
/// while the sync was in flight are in neither list and go next time.
|
||||
Future<void> _clearSentEvents(SyncResponse response) async {
|
||||
for (final rejected in response.rejectedEvents) {
|
||||
debugPrint(
|
||||
'RemoteSyncService: event ${rejected.id} rejected: ${rejected.reason}',
|
||||
);
|
||||
}
|
||||
|
||||
final ids = {
|
||||
...response.acknowledgedEventIds,
|
||||
for (final rejected in response.rejectedEvents)
|
||||
if (rejected.id != null) rejected.id!,
|
||||
};
|
||||
if (ids.isEmpty) return;
|
||||
|
||||
await (database.delete(
|
||||
database.tabEvents,
|
||||
)..where((row) => row.id.isIn(ids))).go();
|
||||
}
|
||||
|
||||
SnapshotTab _toSnapshot(BarTab tab) {
|
||||
return SnapshotTab(
|
||||
id: tab.id,
|
||||
@@ -309,6 +353,7 @@ class RemoteSyncService {
|
||||
command.tabId,
|
||||
paymentMethod: PaymentMethod.fromValue(command.paymentMethod),
|
||||
expectedVersion: command.expectedVersion,
|
||||
commandId: command.id,
|
||||
);
|
||||
|
||||
_eventController.add(
|
||||
|
||||
Reference in New Issue
Block a user