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:
@@ -50,12 +50,26 @@ struct RootView: View {
|
|||||||
// off — no need to wait for the user to open Settings and hit Retry.
|
// off — no need to wait for the user to open Settings and hit Retry.
|
||||||
// Also catches Full Local Sync back up immediately, rather than
|
// Also catches Full Local Sync back up immediately, rather than
|
||||||
// leaving it to wait out the rest of the periodic loop below.
|
// 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) {
|
.task(id: isEffectivelyOnline) {
|
||||||
guard isEffectivelyOnline, let cachingClient = session.cachingClient else { return }
|
guard isEffectivelyOnline, let cachingClient = session.cachingClient else { return }
|
||||||
_ = await cachingClient.flushPendingOperations()
|
|
||||||
if isFullLocalSyncEnabled {
|
if isFullLocalSyncEnabled {
|
||||||
_ = await cachingClient.performFullSync()
|
_ = 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
|
// Fully automatic — this is the only place Full Local Sync actually
|
||||||
// runs from (Settings' "Sync Now" is just an on-demand nudge at the
|
// runs from (Settings' "Sync Now" is just an on-demand nudge at the
|
||||||
|
|||||||
Reference in New Issue
Block a user