Skip to content

Velvet contrib#534

Open
aroundmyroom wants to merge 1011 commits intoIrosTheBeggar:masterfrom
aroundmyroom:velvet-contrib
Open

Velvet contrib#534
aroundmyroom wants to merge 1011 commits intoIrosTheBeggar:masterfrom
aroundmyroom:velvet-contrib

Conversation

@aroundmyroom
Copy link
Copy Markdown

Commit What
f763497 fix: loki backend missing resetPlayCounts / resetRecentlyPlayed
7c00f44 perf: SQLite WAL PRAGMA tuning (synchronous, cache, temp_store)
1ca8fa0 perf: COUNT+OFFSET random song selection — eliminates 123K-row heap load
4ab9baf fix: rate-song and scrobble fail for child-vpath files

Nishant Jain and others added 29 commits January 23, 2025 07:18
…me-for-shared-playlist

feat: format expire date on admin ui
fixes path traversal with album-art
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SQLite backend already had these functions but loki backend was missing
them, causing parity gaps when running with the loki DB engine.

Cherry-picked from 4508b0c5
Sets synchronous=NORMAL, wal_autocheckpoint=10000, cache_size=-32000
and temp_store=MEMORY on every startup. These are idempotent and safe:

- synchronous=NORMAL prevents 50-200ms fsync stalls on slow storage
  (SD card, spinning HDD) that can cause audio dropouts mid-stream
- wal_autocheckpoint=10000 prevents blocking checkpoints while
  a song is being served via HTTP range requests
- cache_size=-32000 (32 MB) keeps hot B-tree pages in RAM for large
  libraries instead of the 2 MB default
- temp_store=MEMORY eliminates temp-table disk spill during sort queries
The /api/v1/db/random-songs endpoint previously called
getAllFilesWithMetadata() and loaded the entire library into a JS array
just to pick one random index. On a 123K-song library this allocates
~50 MB per request and triggers GC pauses that can stall the event loop.

New approach:
  1. getFilesCount()   — single COUNT(*) query
  2. getFileAtOffset() — single SELECT ... LIMIT 1 OFFSET ?

SQLite resolves a rowid-ordered OFFSET in O(log n) using the primary
B-tree. The heap allocation drops from O(n) to O(1).

Both functions are added to sqlite-backend and loki-backend (loki
retains the array approach internally but exposes the same API).
When a file is accessed via a child vpath (a sub-folder mounted as its
own vpath), rate-song and scrobble would fail with 'File Not Found'
because the DB lookup used the child vpath key but the file was indexed
under the parent vpath at scan time (or vice-versa).

Add a resolveFile() helper in db.js that tries the direct lookup first,
then walks all parent vpaths to find a match by checking whether the
child vpath root is a subdirectory of the parent root and prepending the
relative prefix. Same fallback logic added inline in scrobbler.js.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants