Skip to content

0.14.0#588

Merged
FoxxMD merged 116 commits into
masterfrom
database
May 14, 2026
Merged

0.14.0#588
FoxxMD merged 116 commits into
masterfrom
database

Conversation

@FoxxMD
Copy link
Copy Markdown
Owner

@FoxxMD FoxxMD commented May 7, 2026

Checklist before requesting a review

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

Describe your changes

This PR represents the preliminary changes for multi-scrobbler 0.14.0. It is a major update that touches almost every aspect of MS in some way. The main feature is a database implementation to persist data, however since it will require breaking changes I've folded in other major/breaking changes so that the bandage can be ripped off all at once with this update. Change highlights include:

  • SQLite Database powered by Drizzle
    • Automatic db backups and migrations
    • Create Source/Client entities based on config
    • Persisted Play/Scrobble data and all lifecycle data, associate with Source/Client entities
    • Retention policy to compact lifecycle data and delete old/unused Plays
    • (breaking change) Persistent queues have been refactored into the database instead of file cache
  • (breaking change) Simplified cache config
  • Expanded ENV config for more parity with file/aio
    • names and (new) IDs for Source/clients can set with *_ID= and *_NAME=
    • enable/disable config with *_ENABLE= for all clients/sources
  • Numerous bug fixes that affect < 0.14.0 MS

The DB implementation with queues has additional benefits:

  • much lower memory usage since the queue isn't in memory
  • much faster existing (for Sources) and already-scrobbled duplicate (for Clients) detection using Play data hashes
  • discovered Plays (Sources) are now persisted so backlogged Plays are cleared much faster on startup

From a storage perspective it's also pretty compact:

  • Empty DB => 60kb
  • Plays (no original input or lifecycle)
    • 100 Plays => 160kb
    • 1000 Plays => 1mb
  • Plays with original input only
    • 100 Plays => 356kb
    • 1000 Plays => 3.1mb
  • Plays with all lifecycle data
    • 100 Plays => 680kb
    • 1000 Plays => 6.4mb

This PR is already in a good state for daily usage. I am running it on my own server in "production". There are likely still bugs and config kinks to work out. I need the help of MS users to test out the built PR docker image and report how well it works, or what issues, you run into.

Usage

FoxxMD added 30 commits May 6, 2026 02:56
* add components table
* improve typing for json columns
* fix non-nullable columns
* implement basic entity generation functions
* Implement repository method
* Test that deletes cascade to relations
@FoxxMD
Copy link
Copy Markdown
Owner Author

FoxxMD commented May 12, 2026

RE pglite (#593): the db is excellent, would provide ample headroom for scaling MS in the future, and has similar performance where it counts....but it turns out this all comes with the trade-off of a massive increase in memory usage. Like, 3-4x more memory than 0.13.3 and the sqlite implementation.

I guess this should have been expected since it's basically an in-memory instance of postgres but I was still hoping for a smaller footprint. As detailed here in even the best case scenario with their bleeding edge stuff is still 128MB increase. I was seeing ~400MB after MS settled into normal operations after startup. And ~700MB at peak on startup. Compared to ~300 startup -> ~150 with sqlite.

Maybe this can be reduced in the future. And pglite is an awesome technology that I hope to adopt for other projects. But too many users expect a low memory footprint from MS -- I think many people run it on low-power devices like raspis.

So back to pr-588 and sqlite we go.

@FoxxMD FoxxMD mentioned this pull request May 12, 2026
5 tasks
Lots of cleaned up methods and better framing if db backend ever becomes async again
@owendaprile
Copy link
Copy Markdown
Contributor

Just went ahead and updated my instance. No problems so far, but it looks like this branch has the artist refactor (1b53d22). Should artist MBIDs be written to sources on this branch? I'm not seeing them for teal.fm.

From what I can see, the teal.fm play record should support both.

Logs
[2026-05-12 17:57:17.696 +0000] INFO   : [App] [Scrobblers] [Tealfm - teal.fm] Scrobbled (Backlog) => (Plex) Björk - Pagan Poetry @ 2026-05-12T17:52:01+00:00 (S)
[2026-05-12 17:57:16.690 +0000] DEBUG  : [App] [Scrobblers] [Tealfm - teal.fm] Added Björk - Pagan Poetry @ 2026-05-12T17:52:01+00:00 (S) to the queue
[2026-05-12 17:57:16.685 +0000] TRACE  : [App] [Scrobblers] [Tealfm - teal.fm] [Dupe] Björk - Pagan Poetry @ 2026-05-12T17:52:01+00:00 (S) => No Match because no existing scrobbles returned from API
[2026-05-12 17:57:16.677 +0000] TRACE  : [App] [Sources] [Plex - Plex (Chert)] Last activity at 17:57:16+00:00 | Next check in 5.00s
[2026-05-12 17:57:16.673 +0000] INFO   : [App] [Sources] [Plex - Plex (Chert)] Discovered => Björk - Pagan Poetry @ 2026-05-12T17:52:01+00:00 (S)
[2026-05-12 17:57:16.666 +0000] TRACE  : [App] [Sources] [Plex - Plex (Chert)] Björk - Pagan Poetry @ 2026-05-12T17:52:01+00:00 (S) => No Match because no existing scrobbles returned from API
[2026-05-12 17:57:16.666 +0000] DEBUG  : [App] [Sources] [Plex - Plex (Chert)] [Play Transform] [preCompare] [YGSp4I] Transform Diff
Original => Final
{
   artists: [
     0: {
       name: "Björk"
+      mbid: "87c5dedd-371d-4a53-9f7f-80522fb7f3cb"
     }
   ]
-  albumArtists: []
   album: "Vespertine"
   track: "Pagan Poetry"
   duration: 315.959 => 315
   meta: {
     brainz: {
       track: "c600710c-137b-3df4-9419-9bed0ccb572b"
       album: "441e153d-6ce6-3a75-aa4e-65f63b88d14f"
-      albumArtist: [
-        "87c5dedd-371d-4a53-9f7f-80522fb7f3cb"
-      ]
+      artist: [
+        "87c5dedd-371d-4a53-9f7f-80522fb7f3cb"
+      ]
+      recording: "66dd332c-d163-4dd6-8b3d-7f5900112e99"
+      releaseGroup: "271faeb3-fdd1-3ebb-80aa-97b3116e9341"
     }
   },
   playDate: "2026-05-12T17:52:01.753Z"
   listenedFor: 315.959
   listenRanges: [
     {
       "start": {
         "timestamp": "2026-05-12T17:52:01.754Z",
         "position": 0
       },
       "end": {
         "timestamp": "2026-05-12T17:57:12.110Z",
         "position": 315.959
       }
     }
   ]
   playDateCompleted: "2026-05-12T17:57:16.122Z"
   repeat: false
 }
[2026-05-12 17:57:16.661 +0000] DEBUG  : [App] [Transformer] [YGSp4I] [Musicbrainz - MusicBrainz] Found exact release using track MBID
[2026-05-12 17:57:16.133 +0000] DEBUG  : [App] [Transformer] [YGSp4I] [Musicbrainz - MusicBrainz] [API] Search Query => recording:"Pagan Poetry" AND artist:"Björk" AND release:"Vespertine"
[2026-05-12 17:57:16.133 +0000] DEBUG  : [App] [Transformer] [YGSp4I] [Musicbrainz - MusicBrainz] [API] Starting search
[2026-05-12 17:57:16.132 +0000] DEBUG  : [App] [Transformer] [YGSp4I] [Musicbrainz - MusicBrainz] [Basic Search] Searching by artist/album/track
[2026-05-12 17:57:16.132 +0000] DEBUG  : [App] [Transformer] [YGSp4I] [Musicbrainz - MusicBrainz] Search type isrc did not meet prerequesites: Play does not have ISRC
[2026-05-12 17:57:16.131 +0000] DEBUG  : [App] [Transformer] [YGSp4I] [Musicbrainz - MusicBrainz] Desired MBIDs for artists,title,album,duration and Play is missing: title, artists
[2026-05-12 17:57:16.128 +0000] DEBUG  : [App] [Sources] [Plex - Plex (Chert)] [Play Transform] [preCompare] [YGSp4I] Transform start for => Björk - Pagan Poetry @ 2026-05-12T17:52:01+00:00 (S)
[2026-05-12 17:57:16.125 +0000] TRACE  : [App] [Sources] [Plex - Plex (Chert)] Björk - Pagan Poetry @ 2026-05-12T17:52:01+00:00 (S) => No Match because no existing scrobbles returned from API
[2026-05-12 17:57:16.125 +0000] VERBOSE: [App] [Sources] [Plex - Plex (Chert)] [Player 19e606e5-a-Plexamp-Feldspar-owendaprile] (plex://track/5d07cdd5403c640290f7f71b) Björk - Pagan Poetry added after met thresholds with tracked time of 315.96s (wanted 240s) and tracked percent of 100.00% (wanted 50%) and not matching any prior plays
teal.fm record
{
  "$type": "fm.teal.alpha.feed.play",
  "artists": [
    {
      "artistName": "Björk"
    }
  ],
  "duration": 315,
  "trackName": "Pagan Poetry",
  "playedTime": "2026-05-12T17:52:01.753Z",
  "releaseMbId": "441e153d-6ce6-3a75-aa4e-65f63b88d14f",
  "releaseName": "Vespertine",
  "recordingMbId": "66dd332c-d163-4dd6-8b3d-7f5900112e99",
  "submissionClientAgent": "multi-scrobbler/pr588-af5aec2"
}

@FoxxMD
Copy link
Copy Markdown
Owner Author

FoxxMD commented May 12, 2026

@owendaprile should be implemented now. The initial commit was just getting MS working with the new structure, I never went back to actually leverage mbids where they were provided.

@FoxxMD
Copy link
Copy Markdown
Owner Author

FoxxMD commented May 13, 2026

@4rft5 have you tried updating recently? I cannot reproduce the scrobbles page being stale.

@4rft5
Copy link
Copy Markdown

4rft5 commented May 13, 2026

@4rft5 have you tried updating recently? I cannot reproduce the scrobbles page being stale.

I've been following along and updating as new releases are made for the PR but have the same result, all clients Tracks Scrobbled/Recently Scrobbled don't update but the source does.

It might've just been a fluke with my database. I've removed it and restarted the container and it looks like it's made a new one and is counting them again.

image

@FoxxMD
Copy link
Copy Markdown
Owner Author

FoxxMD commented May 13, 2026

The latest builds (c86819b and later) contain a db migration and re-run old cached scrobble conversion.

Your old, cached scrobbles should already have been converted when you started using this pr, so you should see no functional change. But you should see this happen, regardless:

  • logs that it is running a migration
  • backs up your database to ms.db.bak

If you don't see this happen or have any issues with using the newest image, please report it.

@4rft5
Copy link
Copy Markdown

4rft5 commented May 14, 2026

I just updated and tested that LFM 30s fix and it's working. Still no more issues with the stale database. I also went back and checked and it did run the migration and make the backup. All looks good!

@FestiveByteRider
Copy link
Copy Markdown

FestiveByteRider commented May 14, 2026

Out of curiosity when the PR finally gets merged will it include the UI overhaul or has that been pushed back? Had a look for the PR regarding the UI overhaul and couldn't find it anymore but I might be blind o7. Regarding the current DB changes though I haven't noticed any issues since updating to it. Been working great, my discord RPC has been a bit spotty when listening to repeating songs but I'm fairly sure that's unrelated. Big fan of the DB change personally!!

@FoxxMD
Copy link
Copy Markdown
Owner Author

FoxxMD commented May 14, 2026

The UI is being tracked in issue #500 , no pr yet.

There is a storybook folder that has all the current prototype work in it, in master/this pr.

I got a bit into it and then realized I really needed the DB to make it fully useful. Without it there would just be too much kept in memory. So after db gets merged ill be able to resume work on the UI.

Re: repeats, I think someone else has an issue open for repeat issues as well. I'm going to postpone looking into that until after db is released as this change is big enough as it is.

Thanks for the feedback! I've been running it in prod for awhile now too. It's almost ready to rebase/squash and merge.

@FestiveByteRider
Copy link
Copy Markdown

FestiveByteRider commented May 14, 2026

The UI is being tracked in issue #500 , no pr yet.

Right that explains why I couldn't find it hehe. That is a fair reason to put it on hold. Will be exciting when it comes out I shall say, the photos of it I've seen so far look really cool.

Re: repeats, I think someone else has an issue open for repeat issues as well. I'm going to postpone looking into that until after db is released as this change is big enough as it is.

Yeah it's not a huge deal to me personally, my songs scrobble to my Koito server fine I just noticed my Discord RPC would just not display randomly. Which personally isn't a big deal I just have it because it's fun to make things fancy.
Regarding the UI do I just had another look and noticed that the colour scheme has changed, is that going to be a preset thing like it is currently or will it offer some customization? Think it'd look peak with pink accents :3

FoxxMD added 3 commits May 14, 2026 12:54
* Granular persistence of successfully migrated scrobbles
* Don't delete cache after processing
* reduce logging noise and improve wording
* update upgrade wording wrt cache migration
* Use ErrorLike or ErrorIsh for error utilities, rather than requiring object be an Error instance
* Render error summary on dead scrobble page and have copy action include all error data
* serialize errors when sending through api
* fix error assignment for new dead scrobbles
@github-actions
Copy link
Copy Markdown
Contributor

📦 A new release has been made for this pull request.

To play around with this PR, pull an image:

  • foxxmd/multi-scrobbler:pr-588

Images are available for x86_64 and ARM64.

Latest commit: 38d7a9c

@FoxxMD
Copy link
Copy Markdown
Owner Author

FoxxMD commented May 14, 2026

@FestiveByteRider Think it'd look peak with pink accents :3

The new ui is using Chakra UI for the framework and it has pretty granular theming functionality. I haven't looked into it much but it looks like its pretty easy to create custom color palettes.

The only drawback is that the frontend is bundled when the docker image is built so any themes would need to be built into the source rather than being user-supplied at container runtime. It looks like chakra can work with multiple preset themes but it will require some work since it's not an out-of-the-box feature

Here's a more involved implementation, for my future reference or anyone else who wants to implement this and submit a pr: https://www.crema.us/blog/make-a-custom-color-theme-switcher-with-chakra-ui-and-semantic-tokens

@FoxxMD FoxxMD merged commit abe7586 into master May 14, 2026
11 checks passed
@FoxxMD
Copy link
Copy Markdown
Owner Author

FoxxMD commented May 14, 2026

Progress so far has been released as 0.14.0-beta.1 and a new issue has been opened to track any problems. Please move further discussion to the new issue, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request safe to test trusted to build image

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants