Skip to content

feat(sdk): resilient registration, heartbeat backoff, ServiceAPIKey#3

Merged
davidfic merged 2 commits intomainfrom
feat/sdk-resilient-heartbeat
Apr 16, 2026
Merged

feat(sdk): resilient registration, heartbeat backoff, ServiceAPIKey#3
davidfic merged 2 commits intomainfrom
feat/sdk-resilient-heartbeat

Conversation

@davidfic
Copy link
Copy Markdown
Contributor

Summary

Three SDK additions for zero-config stack deployments where apps auto-connect through Pulse without manual configuration.

`NewWithRetry`

Retries registration with exponential backoff (2s → 4s → 8s → 16s → 32s → 32s, ~2 min total). Returns `nil` without error if `PulseURL` is empty (integration disabled). Returns `nil` + error if all attempts fail — the caller continues in standalone mode. Consumers no longer need their own retry wrapper around `New()`.

Resilient heartbeat

Consecutive heartbeat failures trigger exponential backoff on the interval (30s → 45s → 67s → ... → 5m cap). After 5 consecutive failures, the client attempts re-registration in case Pulse restarted and lost the service entry. On recovery, the interval resets and a log line confirms reconnection.

`ServiceAPIKey` config field

Optional. If set, included in the registration payload so services discovered via Pulse's registry can authenticate with the originating service. Enables auto-discovery: Pilot discovers Haul through Pulse and uses the shared API key to send torrent grabs without manual download-client setup.

Test plan

  • `go test -race ./pkg/sdk/...` passes
  • Existing SDK consumers (haul, pilot, prism) continue to compile against this version
  • Tag `v0.2.0` after merge so consumers can pin the new SDK surface

davidfic and others added 2 commits April 16, 2026 06:40
Three additions to the SDK for zero-config stack deployments:

NewWithRetry — retries registration with exponential backoff (2s, 4s,
8s, 16s, 32s, 32s — ~2 minutes total). Returns nil if Pulse URL is
empty (integration disabled) or if all attempts fail (caller should
continue standalone). Consumers no longer need to wrap New() in their
own retry loops.

Resilient heartbeat — consecutive failures trigger exponential backoff
on the heartbeat interval (30s → 45s → 67s → ... → 5m cap). After 5
consecutive failures, the client attempts re-registration in case Pulse
restarted and lost the service entry. On recovery, the interval resets
to the configured default and a log line confirms reconnection.

ServiceAPIKey — optional Config field. If set, included in the
registration payload as "service_api_key" so other services that
discover this one via Pulse can authenticate with it. Enables
auto-discovery flows where Pilot/Prism discover Haul and need its
API key to send torrent grabs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…-register

Two fixes to the auto-download-client creation that fires when a
download-client service (like Haul) registers with Pulse:

1. The API key from the registering service is now stored as the
   download client's Password field. Previously the auto-created
   entry had an empty password, so Pilot/Prism couldn't authenticate
   with Haul when they synced the download client from Pulse.

2. Re-registration (service restart, new port or key) now updates
   the existing download-client entry instead of silently returning.
   This handles the case where Haul restarts on a different port or
   regenerates its API key — the download-client entry stays current.

Also fixes an SDK field name mismatch: the register payload was
sending "service_api_key" but the server's registerInput expects
"api_key". Changed the SDK to send "api_key" to match.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@davidfic davidfic merged commit 15a3f32 into main Apr 16, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant