Skip to content

relay: connection registry — server-id → binary + server-id → [phone] thread-safe maps #3

@ilmoniemi

Description

@ilmoniemi

User Story

As a developer building the relay's routing layer, I want a thread-safe Registry type that maps server-ids to a single binary WS connection (1:1) and to a list of phone WS connections (1:N), with race-tested operations for register / unregister / lookup / list, so that the WS upgrade tickets and the frame-forwarding loop have a single canonical place to coordinate connections.

Context

Foundational data structure for the relay's routing core. Every later ticket (/v1/server upgrade #4, /v1/client upgrade #5, frame forwarding #6, heartbeat #7, grace period #8, health endpoint #10) reads or writes through this registry. Filed second (after #1 envelope) because everything stacks on it.

The registry holds opaque connection handles — interfaces with the methods routing needs (Send([]byte) error, ConnID() string, Close()), not concrete WS types. This keeps the registry testable with mock connections and lets the WS upgrade tickets choose the WebSocket library without rebuilding the registry.

Acceptance Criteria

  • New file internal/relay/registry.go exporting:
  • Tests in internal/relay/registry_test.go covering:
    • ClaimServer succeeds when slot empty; second claim returns ErrServerIDConflict; ReleaseServer + reclaim succeeds.
    • RegisterPhone succeeds only when binary holds the server-id; ErrNoServer when not.
    • UnregisterPhone removes the right phone (by ConnID) and leaves siblings untouched.
    • PhonesFor returns a snapshot — modifying the returned slice must NOT affect the registry's internal state.
    • Counts() returns expected values across the full lifecycle.
    • Race tests (go test -race -count=20) hammering ClaimServer / ReleaseServer / RegisterPhone / UnregisterPhone / BinaryFor concurrently from many goroutines without data races.
  • Doc comments on every exported symbol explaining contract + concurrency guarantees.

Technical Notes

Size Estimate

S — single new file, ~80 LOC + ~120 LOC tests with race coverage. 2 new exported types (Conn, Registry); the rest are methods and sentinel errors.

Metadata

Metadata

Assignees

No one assigned

    Labels

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

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions