Skip to content

Latest commit

 

History

History
103 lines (85 loc) · 5.32 KB

File metadata and controls

103 lines (85 loc) · 5.32 KB

fitz-go Public Contract

This document summarizes the production-facing contract of the public github.com/cntryl/fitz-go/v2/fitz package.

Routes

The Go client validates route shape for ergonomics: scheme, path segment count, empty segments, and wildcard placement allowed for the called method. It does not validate route existence, permissions, authorization, realm semantics, resource names, or auth claims, and it does not normalize route strings.

KV, Queue, Stream, Notice, RPC worker, and Schedule registrations accept exact routes plus whole-segment * and ** patterns, including wildcard realms. KV, Queue, and Stream patterns must be capable of matching three segments; Schedule patterns must match four; Notice and RPC have flexible depth. The broker permits 128 wildcard registrations per domain and session; exact registrations do not consume that quota. Lease subscriptions are different: they accept only an exact lease://realm/area/resource route.

Notifications always expose the exact concrete delivery route. Queue availability notifications additionally expose ready, delayed, and inflight message counts. Duplicate local registrations for the same original string share one wire registration and reconnect restores active registrations.

Queue reserves accept general whole-segment patterns capable of matching three segments. Stream READ and SUBSCRIBE accept concrete resources, realm/area/*, realm/*/*, or stream://**; Stream LAST is concrete-route only. Every returned QueueItem and StreamReadItem exposes the exact concrete matched route, and Stream event records expose it through StreamRecord.Route. Route-less reserve/read/last responses are not supported. If any item contains an invalid concrete route, the entire response fails closed; the client never returns a partial reservation or read batch.

Queue enqueue preserves the immediate Enqueue call and exposes delayed visibility through EnqueueWithOptions(..., WithQueueEnqueueDelaySeconds(n)).

Lifecycle And Resilience

  • Connect(ctx) is one-shot for the initial connection. Concurrent or repeated calls while connected return nil without creating a second transport.
  • Automatic reconnect is enabled by default after the first successful connect. WithReconnect(false, ..., ...) disables it; maxAttempts=0 means unlimited.
  • Heartbeat is enabled by default. WebSocket uses ping/pong; TCP uses socket keepalive and never fabricates Fitz protocol frames.
  • Automatic retries are enabled by default for the narrow replay-safe set: KV Get/Scan, Stream Read/ReadPage/Peek/Metadata, Lease Query, and Queue Enqueue only after an explicit retryable broker rejection.
  • The outbound request queue is bounded. When saturated, operations fail with ErrRequestQueueFull.
  • Detached subscription callbacks use a separate bounded queue. Configure it with WithAsyncHandlerQueueCapacity (default 1024) and configure executing callbacks independently with WithAsyncHandlerMaxConcurrency (default 256). The receive loop never waits for queue space.
  • Every KV, Notice, Queue, Lease, Schedule, and Stream callback subscription exposes Completion() <-chan error. Explicit unsubscribe yields nil. Saturation yields *AsyncHandlerOverflowError, terminates that local registration, and attempts a best-effort wire unsubscribe when it was the final local registration. Queue/Stream polling iterators and Schedule push iterators surface the same terminal error through Iterator.Err().
  • RPC workers retain their protocol-level backpressure response on saturation; they are not converted to subscription completion errors.
  • Async-handler saturation increments fitz.async_handlers.saturated; active and queued work are observable through fitz.async_handlers.active and fitz.async_handlers.queued.
  • Schedule backend unavailability and broker saturation use ErrCodeScheduleBackendError (7010). IsRetryable classifies that code as retryable subject to operation safety. It is distinct from cron and parse errors and is never mapped to malformed schedule input.

Handles And Wake Helpers

Stateful handles are bound to the connection that created them. QueueItem, Lease, KVTx, and StreamSession handles from a previous connection fail fast with ErrStaleHandle after reconnect or close.

Managed WithLease callbacks receive their immutable admission fencing epoch through LeaseAuthorityFromContext. The snapshot is copied from the final successful ACQUIRE, including a deferred queue grant, before application code starts. Renewal may rotate the private live credential but never changes the callback snapshot. Fencing tokens are ordered only for successive owners of the same lease route; external stores retain the greatest accepted value and reject lower values. Lease and LeaseInfo continue to hide raw live credentials, and QUERY is not used to recover admission authority.

NewWakeGate, ReserveWhenAvailable, ReadWhenCommitted, and WaitForNotifications support Go-native consumer loops. Subscriptions are wake signals only for queue and stream helpers; reserve/read calls remain authoritative.

Verification

Fast local verification must pass without Docker:

go test ./...

Broker-backed acceptance and conformance are opt-in:

docker compose up -d
go test -tags=integration ./test ./test/conformance/...