Oke, longer timeout values.
This commit is contained in:
+43
-1
@@ -204,7 +204,9 @@
|
|||||||
id action (length (playback-agent-commands agent)))
|
id action (length (playback-agent-commands agent)))
|
||||||
command))))
|
command))))
|
||||||
|
|
||||||
(define agent-heartbeat-timeout-seconds 10)
|
;; Allow mobile network interruptions without discarding the playback session
|
||||||
|
;; and pending commands while the agent continues playing cached audio.
|
||||||
|
(define agent-heartbeat-timeout-seconds 120)
|
||||||
|
|
||||||
(define (prune-stale-agents! value)
|
(define (prune-stale-agents! value)
|
||||||
(with-state-lock
|
(with-state-lock
|
||||||
@@ -1834,6 +1836,46 @@
|
|||||||
rackunit
|
rackunit
|
||||||
racket/file)
|
racket/file)
|
||||||
|
|
||||||
|
(test-case "agent survives a mobile interruption and expires after prolonged silence"
|
||||||
|
(let* ((app-id (make-string 64 #\c))
|
||||||
|
(value (make-player '() #:playlist-keystore #f #:local-output? #f
|
||||||
|
#:allowed-agent-ids (list app-id))))
|
||||||
|
(dynamic-wind
|
||||||
|
void
|
||||||
|
(λ ()
|
||||||
|
(player-agent-register! value (hasheq 'appId app-id))
|
||||||
|
(let* ((agent (agent-by-id value app-id))
|
||||||
|
(session (playback-session-for! value "anonymous"))
|
||||||
|
(id (agent-renderer-id app-id))
|
||||||
|
(command (enqueue-agent-command! value agent "pause")))
|
||||||
|
(set-playback-session-selected-id! session id)
|
||||||
|
(set-playback-session-backend! session agent)
|
||||||
|
(set-playback-session-backend-kind! session 'agent)
|
||||||
|
(set-playback-session-state! session 'playing)
|
||||||
|
(hash-set! (player-renderer-owners value) id session)
|
||||||
|
;; A minute without polls must preserve the renderer and its owner.
|
||||||
|
(set-playback-agent-last-seen! agent (- (current-seconds) 60))
|
||||||
|
(prune-stale-agents! value)
|
||||||
|
(check-eq? (agent-by-id value app-id) agent)
|
||||||
|
(check-equal? (playback-session-selected-id session) id)
|
||||||
|
(check-eq? (playback-session-backend session) agent)
|
||||||
|
(check-eq? (playback-session-state session) 'playing)
|
||||||
|
(check-eq? (hash-ref (player-renderer-owners value) id #f) session)
|
||||||
|
;; Reconnection delivers the pending command and refreshes liveness.
|
||||||
|
(check-equal? (hash-ref (player-agent-poll! value (hasheq 'appId app-id))
|
||||||
|
'command)
|
||||||
|
command)
|
||||||
|
(prune-stale-agents! value)
|
||||||
|
(check-eq? (agent-by-id value app-id) agent)
|
||||||
|
(set-playback-agent-last-seen! agent (- (current-seconds) 121))
|
||||||
|
(prune-stale-agents! value)
|
||||||
|
(check-false (agent-by-id value app-id))
|
||||||
|
(check-false (renderer-by-id value id))
|
||||||
|
(check-false (playback-session-backend session))
|
||||||
|
(check-eq? (playback-session-state session) 'stopped)
|
||||||
|
(check-false (hash-ref (player-renderer-owners value) id #f))))
|
||||||
|
(λ () (player-close! value)))))
|
||||||
|
|
||||||
(test-case "playlist versions cache 1000 tracks and follow user mutations"
|
(test-case "playlist versions cache 1000 tracks and follow user mutations"
|
||||||
(let ((value (make-player '() #:playlist-keystore #f #:local-output? #f)))
|
(let ((value (make-player '() #:playlist-keystore #f #:local-output? #f)))
|
||||||
(dynamic-wind
|
(dynamic-wind
|
||||||
|
|||||||
@@ -124,6 +124,12 @@ renderers. The server can prefetch the next track to an agent for gapless
|
|||||||
transitions. A 256-bit application ID identifies the agent; the server's
|
transitions. A 256-bit application ID identifies the agent; the server's
|
||||||
@tt{[playback-agents]} allowlist decides which agents may connect.
|
@tt{[playback-agents]} allowlist decides which agents may connect.
|
||||||
|
|
||||||
|
The server keeps an agent's playback session and pending commands for up to
|
||||||
|
two minutes without a status update, allowing brief mobile network outages.
|
||||||
|
Polling within that period refreshes the connection; after longer silence,
|
||||||
|
the server removes the agent from the available outputs. Already downloaded
|
||||||
|
audio can continue playing on the agent during an interruption.
|
||||||
|
|
||||||
Both agents retain downloaded tracks in a local disk cache with a budget of
|
Both agents retain downloaded tracks in a local disk cache with a budget of
|
||||||
1 GB (1,000,000,000 bytes), evicting the least recently used tracks first.
|
1 GB (1,000,000,000 bytes), evicting the least recently used tracks first.
|
||||||
Selecting a cached track reuses its local file when the server address, source
|
Selecting a cached track reuses its local file when the server address, source
|
||||||
|
|||||||
Reference in New Issue
Block a user