unarr/internal
Deivid Soto 1052529ca2 feat(agent): hybrid SSE downlink with long-poll fallback
Replace the bare long-poll wake listener with a hybrid server→agent
downlink that consumes the new GET /api/internal/agent/events SSE stream
first and falls back to the long-poll wake when SSE is unavailable or
silently buffered. Resurrects the SSE client retired with WebRTC
(signal_client.go) as events_client.go — a bounded-scanner reader
(256 KiB line / 1 MiB event) that surfaces heartbeat comments as ping
events so the consumer can detect liveness.

runDownlink dispatches on the new [daemon] downlink config:
  - auto (default): SSE-first; after maxSSEFailures dead/buffered attempts
    fall back to long-poll for 5 min, then re-probe SSE.
  - sse:  SSE only, no fallback (known-good networks / testing).
  - poll: the pre-0.14 long-poll wake only.

A stream is "healthy" only if it delivers a frame within livenessTimeout
(40s vs the server's 15s heartbeat). Crucially the liveness-timeout branch
returns UNHEALTHY even if an earlier frame arrived: a proxy that flushes
the connect preamble (one ping) then stalls must not pin the agent to SSE
forever — that's the partial-buffering case the fallback exists for.

event: command applies typed controls via the same OnControl callback
/agent/sync uses (idempotent); event: sync triggers an immediate sync;
ping is liveness-only. OpenEventStream rides MirrorPool failover for the
initial connect; mid-stream drops close the channel and the loop reopens.

Bump 0.14.0.
2026-06-01 17:31:42 +02:00
..
agent feat(agent): hybrid SSE downlink with long-poll fallback 2026-06-01 17:31:42 +02:00
arr feat(cli): upgrade command, rich status, and version cache 2026-03-31 22:05:43 +02:00
cmd feat(agent): hybrid SSE downlink with long-poll fallback 2026-06-01 17:31:42 +02:00
config feat(agent): hybrid SSE downlink with long-poll fallback 2026-06-01 17:31:42 +02:00
engine fix(agent): surface par2/install/NFS failures instead of degrading silently 2026-06-01 15:52:54 +02:00
funnel fix(agent): surface par2/install/NFS failures instead of degrading silently 2026-06-01 15:52:54 +02:00
library feat(stream): transcode debrid sources to HLS from a URL (hueco #2/2b) 2026-05-31 16:22:14 +02:00
mediaserver feat(cli): upgrade command, rich status, and version cache 2026-03-31 22:05:43 +02:00
parser feat: initial commit — unarr CLI 2026-03-28 11:29:42 +01:00
sentry refactor(sentry): decouple agent import via string-match, rename predicate 2026-05-27 17:03:26 +02:00
ui fix(ci): fix lint errors and pin CI to Go 1.25 2026-03-31 22:15:12 +02:00
upgrade fix(upgrade): fetch releases from TorrentClaw app, not GitHub 2026-05-21 14:46:10 +02:00
usenet fix(agent): surface par2/install/NFS failures instead of degrading silently 2026-06-01 15:52:54 +02:00
vpn feat(vpn): unarr vpn command + report/arbitrate the WireGuard slot 2026-05-22 08:33:02 +02:00