Documentation
¶
Overview ¶
Package httpapi implements an HTTP REST + SSE layer on top of the existing line-based TCP protocol. Each HTTP session owns an in-process virtual connection (net.Pipe) that feeds into the unchanged server.ServeConn handler, so all lock semantics — FIFO ordering, leases, two-phase acquire, signal pub/sub, auto-release on disconnect — are inherited without duplication.
Architecture:
POST /v1/locks/foo session map
│ │
▼ ▼
writeCmd("l\nfoo\n10\n") ──► client side of net.Pipe
│
▼ (server side)
server.ServeConn(ctx, pipeServer, connID)
│
▼
LockManager.Acquire(...)
Command responses and asynchronous "sig ..." push messages share the same stream, so a per-session multiplexer goroutine splits them into respCh (consumed by writeCmd) and sigCh (consumed by SSE handlers).
Index ¶
- Variables
- func Run(ctx context.Context, srv *server.Server, cfg *config.Config, log *slog.Logger) error
- type Bridge
- func (b *Bridge) ConnCount() int64
- func (b *Bridge) CreateSession(remoteIP ...string) (string, error)
- func (b *Bridge) DeleteSession(id string) error
- func (b *Bridge) IdleTimeout() time.Duration
- func (b *Bridge) LockManager() *lock.LockManager
- func (b *Bridge) LookupSession(id string) (*session, error)
- func (b *Bridge) SessionCount() int
- func (b *Bridge) Shutdown()
- func (b *Bridge) Signals() *signal.Manager
- type RegisteredPath
Constants ¶
This section is empty.
Variables ¶
var ErrMaxSessions = errors.New("max sessions reached")
ErrMaxSessions is returned when the bridge has reached its session cap.
var ErrMaxSessionsPerIP = errors.New("max sessions per ip reached")
ErrMaxSessionsPerIP is returned when one remote IP has reached its session cap.
var ErrSessionGone = errors.New("session gone")
ErrSessionGone is returned when a session ID doesn't resolve, either because it was never created or has been swept.
Functions ¶
Types ¶
type Bridge ¶
type Bridge struct {
// contains filtered or unexported fields
}
Bridge owns the set of active HTTP sessions and hands out new ones from /v1/sessions. It shares the LockManager, signal Manager, and connID counter with the TCP server so that cross-transport ordering (FIFO, etc.) is preserved.
func NewBridge ¶
func NewBridge(parent context.Context, srv *server.Server, cfg *config.Config, log *slog.Logger, idleTimeout time.Duration, maxSessions int) *Bridge
NewBridge creates a Bridge wrapping the given server. The bridge uses the server's LockManager and signal Manager via exported accessors.
func (*Bridge) ConnCount ¶
ConnCount returns the number of active TCP connections to the underlying server, so the HTTP stats endpoint can include them.
func (*Bridge) CreateSession ¶
CreateSession mints a fresh session, spins up the virtual connection, and returns the session ID. If the server has an auth token configured, the bridge performs protocol-level authentication transparently so the HTTP client never has to send the `auth` command.
func (*Bridge) DeleteSession ¶
DeleteSession closes the session synchronously, which triggers CleanupConnection in the protocol handler. Returns ErrSessionGone if the ID is unknown.
func (*Bridge) IdleTimeout ¶
IdleTimeout is the advisory timeout surfaced to clients in the session-create response so they know how often to ping when idle.
func (*Bridge) LockManager ¶
func (b *Bridge) LockManager() *lock.LockManager
LockManager returns the shared LockManager. Handlers don't call it directly — they go through session.command — but /v1/stats uses it to synthesize responses without a session round-trip.
func (*Bridge) LookupSession ¶
LookupSession returns the session for the given ID or ErrSessionGone. It also refreshes the session's lastSeen timestamp.
The lastSeen refresh must happen under b.mu so that the idle sweeper — which iterates the map while holding b.mu — cannot observe a stale timestamp for a session that was just looked up and is about to be used. Without this, a sweeper tick falling between the map read and the Store could reap a session the caller has already resolved.
func (*Bridge) SessionCount ¶
SessionCount returns the current number of active sessions. Used by tests and introspection.
type RegisteredPath ¶
type RegisteredPath struct {
// Pattern is the human-readable path template using {placeholder}
// syntax. e.g. "/v1/locks/{key}".
Pattern string
// Methods is the set of HTTP methods this pattern handles.
Methods []string
}
RegisteredPath is a compile-time-visible list of every path the HTTP server handles, with its method(s). The OpenAPI drift test (phase 4) walks this list and asserts 1:1 correspondence with paths documented in openapi.json.