Skip to content

fix(mobile): retry background backup when connectivity returns#30079

Open
santoshakil wants to merge 5 commits into
mainfrom
fix/24545-sync-retry-cx
Open

fix(mobile): retry background backup when connectivity returns#30079
santoshakil wants to merge 5 commits into
mainfrom
fix/24545-sync-retry-cx

Conversation

@santoshakil

@santoshakil santoshakil commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Description

Fixes #24545

Android only. The main backup worker stays unconstrained, a small WorkManager relay remembers whether the next useful run needs CONNECTED or UNMETERED and queues the main worker when the network is back. Repeat failures keep the same relay so backoff is preserved, a real target change replaces it, it survives reboot, and the charging rule is read on every enqueue. Local sync now reports whether it fully completed, a failed sync no longer saves its checkpoint so missed assets get retried instead of skipped for good, and only a trusted empty result clears the relay. Worker cleanup no longer waits across an error zone, so a failed task cant hang the run. Foreground backup, setting handoff timing, auth cleanup and iOS behavior are unchanged.

Tested with the unit condition matrix (both candidate orders, mixed outcomes, early stop, sync failure) and an emulator matrix: offline to connected recovery, mixed cellular in both orders, backoff kept across failures, reboot, process death around the seed, foreground lock, charging. Also ran real device legs on a Pixel 7: offline photo with the app killed landed on the server 22 seconds after connectivity returned, and on real LTE the wifi only setting made no upload attempt at all until wifi came back, checksums verified both times.

@immich-push-o-matic

immich-push-o-matic Bot commented Jul 20, 2026

Copy link
Copy Markdown

📱 Android release APK (universal)6e00cb0244ecee790bf7739c5128daf7bbcb2f5b

Download: https://github.com/immich-app/immich/actions/runs/30079243353/artifacts/8591276732

QR code QR code

Installs as a separate app (applicationId app.alextran.immich.pr30079), so it coexists with the Play Store version and any other PR builds.

@shenlong-tanwen

Copy link
Copy Markdown
Member

The backup setting isn't an either or. Photos can have cellular while videos might have wifi only. The changes made in this PR is not respecting said setting. Also, we have a periodic task on the android side now that runs every 1 hours, so an asset can atmost be in the un-uploaded state only for a maximum of 1 hour, provided the other constraints are met

return BackgroundWorkerSettings(
minimumDelaySeconds: minimumDelaySeconds ?? backup.triggerDelay,
requiresCharging: requireCharging ?? backup.requireCharging,
requiresUnmetered: !(backup.useCellularForPhotos || backup.useCellularForVideos),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be incorrect when the photos and videos have different settings on cellular

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wifi only happens when both toggles are off. if either type may use cellular the worker wakes on any connection since theres work it can do there, and each upload still checks its own setting like before. so photos on cellular and videos off, the worker runs on data, uploads the photo and skips the video, and the video catches up on the next run once wifi is back.. tested exactly this on the emulator. requiring wifi when only one type needs it would hold photo uploads the user allowed on cellular, that felt worse.

@santoshakil

Copy link
Copy Markdown
Collaborator Author

yeah the hourly task caps the delay and we kept it as is, it stays the catch up net. what the constraint adds is the queued worker fires the moment the right network shows up instead of waiting for the next tick, thats the reconnect behavior people in the issue expect. it also stops the one time worker from running while offline or on cellular for a wifi only user, when it cant upload anything anyway. and per type settings still work like before, each upload checks its own toggle, the constraint only decides when the worker wakes, more on that in the review thread.

@shenlong-tanwen

Copy link
Copy Markdown
Member

it also stops the one time worker from running while offline or on cellular for a wifi only user, when it cant upload anything anyway

This is precisely the issue that the requiresUnmetered in the code introduces. A video upload with wifi only and mobile upload with cellular means a freshly taken video is not uploaded until the next hourly run because the condition sets requiresUnmetered to false. Your tests might've incorrectly reported this because if one of this is set to cellular, then the task is setup for CONNECTED and switching from cellular to wifi would not be re-running the task if the previous run ran to completion

The DEFAULT_REQUIRE_UNMETERED might also be incorrect under the default case. The background worker is not just for uploads. Even when it can't upload anything, we still run the task to reconcile with the device state, hash any new assets and sync the new remote data with the app. This means, the run after this would be faster as most things are already processed.

The ideal way to handle this is for separate WorkManager tasks for each type respecting the user setting. The current architecture makes this a bit harder to implement as we use one task for everything

@santoshakil

Copy link
Copy Markdown
Collaborator Author

oh you are right, the constraint also holds back the sync and hash work, i missed that. reworking it.. the task runs with no network rule like before, and a run that skips uploads for network reasons queues a one time retry with the right rule. will update the pr

@santoshakil
santoshakil marked this pull request as draft July 23, 2026 10:06
@santoshakil

Copy link
Copy Markdown
Collaborator Author

reworked it. the main worker runs with no network rule now so sync and hash always run, and a small relay waits for whatever network the skipped uploads actually need, then wakes the main one. mixed settings work and a broken run cant lose the retry anymore. few side fixes along the way, details in the body. ready for another look.

@santoshakil
santoshakil marked this pull request as ready for review July 24, 2026 08:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sync is not re-attempted if connectivity is lost then restored

2 participants