Persistence and Recovery
SyncFM persists in-progress work so a process or network failure does not require blindly restarting submissions.
State database
The CLI defaults to a platform-specific user-state path ending in syncfm/syncfm.sqlite3. Override it with global --database or SYNCFM_DATABASE_PATH. Python callers choose the path passed to create_sync_service().
The parent directory and schema are created automatically. SQLite connections enable foreign keys and use a five-second busy timeout. Schema version 2 is recorded with PRAGMA user_version; databases newer than the installed code are rejected.
Stored entities
sync_sessions: direction, optional profile names, resolved range, and current phasesource_scrobbles: de-duplicated source snapshottarget_scrobbles: de-duplicated target snapshotsync_queue: missing source events, metadata, status, failure stage, and error
Session deletion cascades to all snapshot and queue rows.
Queue statuses are partial, fetching, ready, syncing, synced, and failed. Failures record whether they occurred during metadata or submission.
What resume does
Before continuing, resume normalizes uncertain work:
- interrupted
fetchingmetadata items return topartial; - metadata failures return to
partial; - submission failures return to
ready; and - items left in
syncingare queried at the target for their exact timestamp.
For an interrupted syncing item, the target snapshot at that timestamp is compared using artist, title, and timestamp. If found, the item becomes synced; otherwise it becomes ready and can be submitted.
This reconciliation addresses the ambiguous case where the remote service accepted a submission but the local process stopped before marking it complete.
Resume point by phase
| Stored phase | Work repeated or continued |
|---|---|
created, fetching, failed |
Fetch both snapshots again, then continue |
comparing |
Rebuild the idempotent queue, then continue |
enriching, syncing |
Recover queue states, then continue enrichment/submission |
completed |
Return the stored result path if such a custom-persistence session remains |
The built-in successful path deletes completed sessions, so they do not normally appear in status.
Profile and network checks
A resume must use network objects whose name properties exactly match the stored source and target names. If profile names were stored, supplied profile names must also match.
Current CLI-created sessions store both profiles. Legacy sessions require syncfm resume ID --source NAME --target NAME once, after which those names are saved.
Discard
discard removes only local recovery state. It cannot undo target scrobbles already accepted before the failure. Prefer resume when submission status is uncertain because resume performs target reconciliation.
Operational recommendations
- Keep the database on persistent local storage.
- Back it up before manually inspecting or migrating it, but do not edit it during a run.
- Do not share one database over an unreliable network filesystem.
- Serialize writers that use the same database; the busy timeout reduces brief contention but is not a job scheduler.
- Use separate database paths to isolate applications or independent workloads.
- Keep the profile configuration and keyring available for as long as a session may need resuming.