Skip to content

Request Handlers

Joseph Chacko edited this page Jul 22, 2026 · 2 revisions

Request Handlers & Command Dispatch

Relevant source files

The following files were used as context for generating this wiki page:

This section documents the command processing layer of aurora-daemon. It covers the lifecycle of a client connection, from the initial wire-protocol handshake to the dispatching of specific playback and management commands.

Client Connection Lifecycle

When a client connects to the Unix socket, the daemon invokes handle_client daemon/src/handlers/mod.rs:39-43. This function manages two concurrent tasks for every connected client:

  1. Notification Loop: A spawned task that periodically pushes the current system state (status, theme, volume, queue) to the client daemon/src/handlers/mod.rs:47-69.
  2. Request Loop: The main loop of the function which blocks on read_request to process incoming commands daemon/src/handlers/mod.rs:71-118.

Wire Protocol: read_request

The protocol uses a length-prefixed JSON format. The read_request function daemon/src/handlers/mod.rs:28-37 performs the following:

  1. Reads 4 bytes to determine the message length (Big-Endian u32).
  2. Allocates a buffer of that size.
  3. Reads the exact number of bytes into the buffer.
  4. Deserializes the buffer into a Request enum using serde_json.

Status Notification Loop

The notification loop ensures the client UI remains synchronized with the daemon's internal State. It runs every 200ms daemon/src/handlers/mod.rs:63.

Sequence Data Sent Source Function
Initial Response::Queue state.lock().await.queue daemon/src/handlers/mod.rs:48-52
Initial Response::Theme state.lock().await.theme daemon/src/handlers/mod.rs:54-56
Initial Response::Volume state.lock().await.volume daemon/src/handlers/mod.rs:57-59
Periodic Response::Status status::status daemon/src/handlers/mod.rs:64

Sources: daemon/src/handlers/mod.rs:28-70

Command Dispatch Mapping

The daemon uses a large match statement to route Request variants to their respective handler modules.

Playback & Transport

These handlers modify the Sink or the current_song index within the StateStruct.

Request Variant Handler Function Description
Play(Uuid) enqueue::enqueue Adds song to end; starts playback if queue was empty daemon/src/handlers/enqueue.rs:10.
Pause pause::pause Toggles the rodio::Sink pause state.
Seek(Duration) seek::seek Adjusts playback position in the current stream.
Next(n) next_prev::next Advances n tracks and calls state.add() daemon/src/handlers/next_prev.rs:8-11.
Prev(n) next_prev::prev Rewinds n tracks and calls state.add() daemon/src/handlers/next_prev.rs:24-27.

Queue Operations

Queue management involves manipulating the VecDeque<SongMeta> stored in the global state.

Request Variant Handler Function Logic
Enqueue(Uuid) enqueue_at::enqueue_at Appends song to the end of the queue daemon/src/handlers/enqueue_at.rs:62-65.
PlayNext(Uuid) enqueue_at::enqueue_at Inserts song at index 1 (immediately after current) daemon/src/handlers/enqueue_at.rs:42-48.
ReplaceQueue(Vec<Uuid>) replace_queue::replace_queue Clears queue and populates with new IDs daemon/src/handlers/replace_queue.rs:9-37.
MoveQueue { from, to } move_queue::move_queue Reorders items within the queue VecDeque daemon/src/handlers/move_queue.rs:4-11.
Clear clear::clear Empties the queue and stops playback daemon/src/handlers/clear.rs:4-6.

Sources: daemon/src/handlers/mod.rs:74-115, daemon/src/handlers/enqueue_at.rs:9-88, daemon/src/handlers/replace_queue.rs:9-44

Data Flow: Request to Response

The following diagram illustrates how a Request::Search is processed and how the resulting Response is broadcast back to the client.

Search Request Flow

Title: Search Command Execution Path

sequenceDiagram
    participant C as Client (aurora-player)
    participant H as handle_client
    participant S as handlers::search
    participant ST as StateStruct
    participant DB as SQLite / Index

    C->>H: Send Request::Search(SearchType)
    H->>S: call search(writer, state, query)
    S->>ST: lock() and state.search(query)
    ST->>DB: Query index for matches
    DB-->>ST: Return Vec<SongMeta>
    S->>ST: get_art(song_id) for each result
    S->>C: Send Response::SearchResults(Vec<Song>)
Loading

Sources: daemon/src/handlers/search.rs:4-27, daemon/src/handlers/mod.rs:84

System Interaction Diagram

This diagram bridges the high-level request types to the specific code entities responsible for fulfilling them.

Title: Request Mapping to Internal Entities

graph TD
    subgraph "Request Entry"
        REQ["Request Enum"]
        H_CLI["handle_client (handlers/mod.rs)"]
    end

    subgraph "Playback Handlers"
        ENQ["enqueue_at.rs"]
        NXT["next_prev.rs"]
        PAU["pause.rs"]
    end

    subgraph "Library Handlers"
        SRCH["search.rs"]
        PL["playlist.rs"]
        LK["liked.rs"]
    end

    subgraph "Core State"
        STATE["StateStruct (types.rs)"]
        SINK["rodio::Sink"]
        IDX["state.index (HashMap)"]
    end

    REQ --> H_CLI
    H_CLI --> ENQ
    H_CLI --> NXT
    H_CLI --> SRCH
    
    ENQ --> STATE
    NXT --> SINK
    SRCH --> IDX
    
    subgraph "Auto-Advance"
        WATCH["watcher_thread.rs"]
    end
    
    WATCH -- "sink.empty()" --> STATE
    STATE -- "state.next()" --> SINK
Loading

Sources: daemon/src/handlers/mod.rs:39-119, daemon/src/watcher_thread.rs:6-21, daemon/src/handlers/next_prev.rs:8-11

Key Implementation Details

Auto-Advance Mechanism

The watcher_thread daemon/src/watcher_thread.rs:6-21 acts as a virtual request handler. It polls the rodio::Sink every 100ms. If sink.empty() is true and the queue is not empty, it programmatically triggers state.next(1) and state.add(), then broadcasts the updated queue to all clients via Response::Queue daemon/src/watcher_thread.rs:11-17.

State Synchronization

Most handlers follow a pattern of:

  1. Locking the State daemon/src/handlers/replace_queue.rs:14.
  2. Modifying the internal VecDeque or Sink daemon/src/handlers/replace_queue.rs:35-37.
  3. Dropping the lock daemon/src/handlers/replace_queue.rs:40.
  4. Broadcasting the change to all clients using helpers::send_to_all daemon/src/handlers/replace_queue.rs:42.

Sources: daemon/src/handlers/replace_queue.rs:9-44, daemon/src/watcher_thread.rs:6-21

Clone this wiki locally