Skip to content

relay: /v1/server — defer binary release by 30s grace window #21

@ilmoniemi

Description

@ilmoniemi

User Story

As the relay's /v1/server upgrade handler, I want to switch the binary-disconnect cleanup path from immediate release to a 30-second deferred release, so that a quick reconnect by the same binary lands back in the same server-id slot with its phones still attached.

Context

Implements the wire-spec semantics from pyrycode/pyrycode/docs/protocol-mobile.md § Authentication → Binary → relay: "When the holding connection drops (close, ping timeout, network error), the server-id is released after a 30-second grace period."

The registry-side primitive Registry.ScheduleReleaseServer(serverID, d) already shipped in #20. This ticket is the one-call-site swap on the handler's disconnect-cleanup defer in internal/relay/server_endpoint.go. The existing lesson "defer ReleaseServer(...) must be registered AFTER the successful ClaimServer" (docs/lessons.md) still holds: the new call replaces ReleaseServer in the same defer position.

Acceptance Criteria

  • In internal/relay/server_endpoint.go, the disconnect-cleanup defer in ServerHandler calls reg.ScheduleReleaseServer(serverID, grace) instead of reg.ReleaseServer(serverID). The wsconn.Close() and the server_released log line stay as they are.
  • The grace duration is configurable for tests (constructor parameter, Options struct field, or unexported package-level override — architect's call). Production wiring in cmd/pyrycode-relay/main.go passes 30 seconds.
  • Test in internal/relay/server_endpoint_test.go: a binary that connects, claims, then closes the WS triggers a scheduled (not immediate) release. The test uses a short grace duration so it can assert "still claimed at T+ε, released at T+grace" — e.g. by inspecting Registry state directly, since ScheduleReleaseServer exposes no return value.
  • Existing /v1/server tests still pass unchanged — header-gate, conflict path, and successful claim/release behaviour are not regressed.

Technical Notes

  • Touches one call site in internal/relay/server_endpoint.go plus the wiring in cmd/pyrycode-relay/main.go if a constructor argument is added.
  • Out of scope:

Size Estimate

XS — handler change is a single-call-site swap (~5 LOC) plus a wiring parameter (~5 LOC); the test (~30 LOC) is the bulk.

Split from #8.

Metadata

Metadata

Assignees

No one assigned

    Labels

    security-sensitiveTouches auth, crypto, or internet-exposed input pathssize:xsTiny ticket: <30 lines production code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions