-
Notifications
You must be signed in to change notification settings - Fork 0
Background Threads
Relevant source files
The following files were used as context for generating this wiki page:
The aurora-daemon relies on three specialized background threads to manage system integration, configuration persistence, and playback continuity. These threads operate independently of the primary IPC request-handling loop, ensuring that the daemon remains responsive to external D-Bus signals, filesystem changes, and audio hardware events.
The mpris_thread provides integration with the Linux D-Bus MPRIS2 (Media Player Remote Interfacing Specification) protocol. This allows Aurora to be controlled via system media widgets (e.g., GNOME/KDE shells), hardware media keys, and CLI tools like playerctl.
The implementation is split into two primary components:
-
The Controller: Manages the
mpris-serverinstance and maps D-Bus method calls (Play, Pause, Seek, etc.) toPlayerCommandvariants sent through an internal channel daemon/src/mpris_thread.rs:90-148. -
The Command Loop: Listens for
PlayerCommandvariants and applies them to the globalStatedaemon/src/mpris_thread.rs:31-85.
A synchronization loop runs every 500ms to reconcile the daemon's internal State with the MPRIS2 bus daemon/src/mpris_thread.rs:156-157. It detects changes in the current_song, playback position, and volume, then updates the D-Bus properties accordingly daemon/src/mpris_thread.rs:183-206.
| PlayerCommand | Action on State | IPC Response Triggered |
|---|---|---|
PlayPause |
state.pause() daemon/src/mpris_thread.rs:34
|
Status Update |
Next |
state.next(1) daemon/src/mpris_thread.rs:53
|
Response::Queue daemon/src/mpris_thread.rs:57
|
Prev |
state.prev(1) daemon/src/mpris_thread.rs:61
|
Response::Queue daemon/src/mpris_thread.rs:65
|
SeekOffset |
audio.seek(current + offset) daemon/src/mpris_thread.rs:72
|
Status Update |
SetVolume |
sink.set_volume(vol) daemon/src/mpris_thread.rs:82
|
Status Update |
Data Flow: D-Bus to Daemon State
graph TD
subgraph "D-Bus Ecosystem"
A["External Controller (playerctl)"] -- "DBus Method" --> B["mpris_server::Player"]
end
subgraph "mpris_thread.rs"
B -- "Callback" --> C["UnboundedSender<PlayerCommand>"]
C -- "rx.recv()" --> D["Command Loop"]
end
subgraph "State Management"
D -- "lock().await" --> E["StateStruct"]
E -- "audio.seek()" --> F["Rodio/Symphonia"]
E -- "next()" --> G["Queue Management"]
end
G -- "send_to_all" --> H["Connected Clients"]
Sources: daemon/src/mpris_thread.rs:8-18, daemon/src/mpris_thread.rs:31-85, daemon/src/mpris_thread.rs:90-148.
The theme_thread manages the hot-reloading of the application's visual style. It monitors the config.toml file located in the user's configuration directory.
-
Initialization: On startup,
get_config()reads~/.config/aurora-player/config.toml. If the file is missing or malformed, it returns a default "Gruvbox-inspired" palette daemon/src/theme_thread.rs:6-30. -
File Watching: Uses the
notifycrate to watch the configuration directory daemon/src/theme_thread.rs:38-39. -
Broadcast: When a
Modify,Create, orRemoveevent is detected, the thread re-parses the TOML file, updates theStateStruct, and broadcasts aResponse::Themeto all connected clients daemon/src/theme_thread.rs:43-47.
The Theme struct (and config.toml) defines 10 color keys, primarily focusing on background depths (bgd0-bgd4), text contrasts (txt1-txt2), and an accent color (acct) themes/mavenblack.toml:1-11.
Theme Update Sequence
sequenceDiagram
participant FS as Filesystem (config.toml)
participant TW as theme_thread::init
participant S as StateStruct
participant C as Connected Clients
TW->>FS: watch(RecursiveMode::Recursive)
Note over FS: User saves config.toml
FS-->>TW: EventKind::Modify
TW->>TW: get_config()
TW->>S: lock() & update theme
TW->>C: send_to_all(Response::Theme)
Sources: daemon/src/theme_thread.rs:6-30, daemon/src/theme_thread.rs:32-54, themes/.
The watcher_thread is a lightweight loop responsible for maintaining playback continuity. While rodio handles the actual audio buffer feeding, this thread monitors the status of the Rodio::Sink to determine when a track has finished.
The thread polls the state every 100ms daemon/src/watcher_thread.rs:9:
-
Check Sink: It queries
state_locked.sink.empty()daemon/src/watcher_thread.rs:11. - Check Queue: It ensures the queue is not empty daemon/src/watcher_thread.rs:11.
-
Advance: If the sink is empty and a queue exists, it calls
state_locked.next(1)to increment the index andstate_locked.add()to decode the next file into the sink daemon/src/watcher_thread.rs:12-13. - Notify: It broadcasts the updated queue state to all clients so the UI can update the "Now Playing" indicators daemon/src/watcher_thread.rs:15-17.
Entity Mapping: Watcher to Audio Engine
graph LR
subgraph "watcher_thread.rs"
W["init() loop"]
end
subgraph "StateStruct (types.rs)"
S["sink: rodio::Sink"]
Q["queue: VecDeque<SongMeta>"]
A["audio: Option<SeekableAudio>"]
end
W -- "sink.empty()" --> S
W -- "next(1)" --> Q
W -- "add()" --> A
A -- "decode" --> S
Sources: daemon/src/watcher_thread.rs:6-21, daemon/src/handlers/replace_queue.rs:35-37.
Overview
aurora-daemon
- Background Service
- Startup & State Init
- Request Handlers & Dispatch
- Playback Engine & Audio
- Library Indexing & Watching
- Playlists, Liked & History
- Background Threads
aurora-protocol
aurora-player
Reference