mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-11 07:29:14 +01:00
address final review: coalesce sync requests, fix page-cap edge
- SyncManager now uses a conflated request channel instead of tryLock, so a request that arrives during a sync (e.g. add-source switching the active server) is queued and runs afterwards against the then-active source instead of being dropped. - Paged loops count raw server rows, not accepted entities, so an empty-id row on an otherwise full page no longer ends the scan early and prunes the unseen tail. - The cap now fails when the page just past it is non-empty, not only when it is full, matching the bound the error message reports. - fetchRank rethrows the cap instead of downgrading an over-cap album scan to empty ranks. - Docs: the mutex lives in SyncManager, and the prune still holds the existing-id set.
This commit is contained in:
@@ -106,7 +106,7 @@ Images: grids and lists request a 256 px `getCoverArt` thumbnail; the 120 dp det
|
||||
|
||||
## Sync
|
||||
|
||||
`SyncService.sync()` is serialized by a mutex in `SourceRepository`, so overlapping sync requests cannot interleave. It walks five entities in sequence — artists, albums, songs, playlists and playlist songs — and each one is a cold `Flow` from `MusicSource` that the service collects: it remembers the IDs already in the local mirror, upserts every batch as it arrives (one `immediateTransaction` per ~500-row batch), crosses those IDs off, and after that entity's stream ends deletes whatever is left, i.e. the rows the server no longer lists. The parser reads the HTTP response stream directly, so neither the raw XML nor the whole library ever sits in memory at once.
|
||||
`SyncService.sync()` is serialized by `SyncManager`, which coalesces duplicate requests. It walks five entities in sequence — artists, albums, songs, playlists and playlist songs — and each one is a cold `Flow` from `MusicSource` that the service collects: it remembers the IDs already in the local mirror, upserts every batch as it arrives (one `immediateTransaction` per ~500-row batch), crosses those IDs off, and after that entity's stream ends deletes whatever is left, i.e. the rows the server no longer lists. The parser reads the HTTP response stream directly, so the fetched library is streamed page by page rather than materialised wholesale, though the prune still holds the existing ID set to diff against.
|
||||
|
||||
Songs have a primary and a fallback fetch. The primary probes `search3` with an empty query once (memoized per source); if the server supports it, the library is paged through `search3` 500 songs at a time. Otherwise the fallback pages `getAlbumList2` and then issues one `getAlbum` per album — it works everywhere but costs a request per album instead of per 500 songs. Every paged loop stops on a short page and is capped at 1000 pages. Playlists are fetched whole, and their songs are stored by position so a playlist that got shorter (or was emptied) is trimmed at the end.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user