BlueHuskyStudios / BlueHuskyStudios/DeadassSimpleMediaPlayer

Move persistence I/O off the main actor

Open
#46 1 comment 0 reactions 0 assignees View on GitHub
Automatically found Concurrency
Dominant language
Swift
Stars
0
Forks
3
Avg merge
2d 22h
Merged PRs (30d)
9

Description

`JSONDocumentStore`'s methods are synchronous, and every caller is `@MainActor`:

- `saveNowPlayingSnapshotNow()` — on pause, on backgrounding, and from the debounced task
- `saveHistoryNow()` — **on every recorded play**
- `loadIfNeeded()` / `loadAllSavedPlaylists()` — at launch

Each call is `JSONEncoder.encode` + atomic `Data.write`, or `Data(contentsOf:)` + decode. Because `MediaReference` carries multi-kilobyte bookmark `Data` that base64-inflates in JSON, a queue of a few hundred tracks is a multi-megabyte encode-and-write **on the main thread**.

History is the sharpest edge: `saveHistoryNow()` rewrites the *entire* history file every time a track crosses the one-second threshold. With `.forever` retention (the default) that file only grows.

`JSONDocumentStore` is already a `Sendable` struct with no shared mutable state — making it an `actor`, or giving it `async` methods, would move all of this off main without changing any model.

Contributor guide

Open the contributing guide

Research direction

Start by locating JSONDocumentStore and its listed callers: saveNowPlayingSnapshotNow(), saveHistoryNow(), loadIfNeeded(), and loadAllSavedPlaylists(). Trace the launch, pause, backgrounding, debounced-task, and recorded-play paths; done means persistence encoding and file I/O no longer run on the @MainActor while existing model behavior remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
performance
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.