fix(offline): retry pending sync with a cooloff instead of one shot

The auto-flush that runs when reconnecting (or turning Offline Mode
back off) only ever tried once — any operation that still failed on
that attempt sat stuck until the user manually hit Retry or
connectivity changed again. Now retries every 5 minutes for as long as
anything's still pending and the signal stays on, stopping on its own
once the queue is empty. Full Local Sync's existing 20-minute loop is
unaffected/separate.
This commit is contained in:
2026-08-15 15:43:00 +01:00
parent 21e81feed7
commit bf9eec6a9b
+15 -1
View File
@@ -50,12 +50,26 @@ struct RootView: View {
// off no need to wait for the user to open Settings and hit Retry.
// Also catches Full Local Sync back up immediately, rather than
// leaving it to wait out the rest of the periodic loop below.
//
// The flush itself gets a retry loop with a cooloff, not just one
// attempt: a single transient failure (one bad operation, a blip
// mid-flush) used to leave everything else stuck until the user
// manually hit Retry or connectivity changed again. Keeps retrying
// every 5 minutes for as long as *anything* is still pending and
// this signal stays on stops on its own once the queue is empty,
// and `.task(id:)` cancels/restarts it automatically if
// isEffectivelyOnline flips again in the meantime.
.task(id: isEffectivelyOnline) {
guard isEffectivelyOnline, let cachingClient = session.cachingClient else { return }
_ = await cachingClient.flushPendingOperations()
if isFullLocalSyncEnabled {
_ = await cachingClient.performFullSync()
}
while !Task.isCancelled {
_ = await cachingClient.flushPendingOperations()
let remaining = await cachingClient.pendingOperations()
guard !remaining.isEmpty else { break }
try? await Task.sleep(for: .seconds(300))
}
}
// Fully automatic this is the only place Full Local Sync actually
// runs from (Settings' "Sync Now" is just an on-demand nudge at the