provider

package
v1.0.25 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 31, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package provider is a WebSocket CRDT transport reference implementation.

It authenticates the HTTP upgrade, compares an exact replica.Manifest before accepting binary changes, bounds messages and queued writes, and uses a replica.Inbox to tolerate duplicate and out-of-order delivery. It deliberately does not add TLS, durable storage, replay/outbox handling, membership, or a tombstone-GC policy. Applications must provide those boundaries themselves.

Index

Constants

View Source
const (
	// Subprotocol identifies the reference provider's control and binary-change
	// envelope. It is not a CRDT frame format version.
	Subprotocol = "crdt-sync-v1"
	// BatchSubprotocol adds a bounded batch envelope while retaining a complete
	// Dot and canonical CRDT delta for every contained change. It is opt-in so
	// v1 peers retain their original wire contract.
	BatchSubprotocol = "crdt-sync-v2"
	// AwarenessSubprotocol adds ephemeral awareness-v1 messages to the v2
	// envelope. Awareness is never part of a CRDT delta, checkpoint, or
	// replica.Frontier, so it remains explicitly negotiated and optional.
	AwarenessSubprotocol = "crdt-sync-v3"
)

Variables

View Source
var (
	// ErrInvalidConfig reports a missing or unsafe provider configuration.
	ErrInvalidConfig = errors.New("websocket provider: invalid configuration")
	// ErrUnauthorized reports authentication or actor authorization failure.
	ErrUnauthorized = errors.New("websocket provider: unauthorized")
	// ErrClosed reports use of a closed client.
	ErrClosed = errors.New("websocket provider: client is closed")
	// ErrBatchUnsupported reports a batch operation on a v1 connection.
	ErrBatchUnsupported = errors.New("websocket provider: batch subprotocol is not enabled")
	// ErrBatchLimit reports a batch that exceeds the configured item or message
	// limit before it reaches the network.
	ErrBatchLimit = errors.New("websocket provider: batch limit exceeded")
	// ErrAwarenessUnsupported reports an awareness operation attempted without
	// the explicitly negotiated awareness subprotocol.
	ErrAwarenessUnsupported = errors.New("websocket provider: awareness unsupported")
)

Functions

This section is empty.

Types

type Authenticate

type Authenticate func(*http.Request) (Peer, error)

Authenticate authenticates one HTTP upgrade request before it becomes a WebSocket connection. Returning an error rejects the request with HTTP 401.

type Authorize

type Authorize func(Peer, replica.Manifest, replica.Dot) error

Authorize binds a proposed CRDT change to an authenticated peer and its negotiated manifest. At minimum it should prevent one peer from publishing under another logical replica actor.

type AuthorizeAwareness added in v1.0.24

type AuthorizeAwareness func(Peer, replica.Manifest, awareness.Update) error

AuthorizeAwareness binds a transient awareness actor to an authenticated peer. It is intentionally separate from Authorize because awareness clocks are not replica dots and must not be granted durable mutation authority.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client maintains one reference-provider WebSocket connection. It does not persist an outbox or automatically reconnect; callers decide retry and recovery policy.

func Dial

func Dial(ctx context.Context, endpoint string, manifest replica.Manifest, config ClientConfig) (*Client, error)

Dial authenticates the WebSocket handshake through config.Header, verifies that the server returns the exact manifest, then starts receiving binary changes. The endpoint should use wss in production after the application has configured TLS.

func (*Client) Close

func (client *Client) Close() error

Close terminates the connection without attempting to make a client-side durability claim. Callers should persist their own checkpoint first when a graceful recovery boundary is required.

func (*Client) Done

func (client *Client) Done() <-chan struct{}

Done closes when the receive loop stops.

func (*Client) Err

func (client *Client) Err() error

Err returns the first non-local connection or callback failure.

func (*Client) Publish

func (client *Client) Publish(ctx context.Context, change replica.Change) error

Publish validates change against the connection manifest, then transmits its canonical delta envelope. A caller may safely retry a change after an ambiguous network result; receiver inboxes and the concrete CRDT must remain idempotent.

func (*Client) PublishAwareness added in v1.0.24

func (client *Client) PublishAwareness(ctx context.Context, update awareness.Update) error

PublishAwareness transmits one ephemeral actor state after local validation. It does not modify a replica.Inbox or establish a durability boundary.

func (*Client) PublishBatch added in v1.0.21

func (client *Client) PublishBatch(ctx context.Context, changes []replica.Change) error

PublishBatch validates and sends a bounded group of independently identified changes in one WebSocket message. The server admits each Dot individually, so retry and outbox logic must retain every original change.

type ClientConfig

type ClientConfig struct {
	Header          http.Header
	Policy          crdt.ProtocolPolicy
	MaxMessageBytes int
	MaxActorBytes   int
	// EnableBatches negotiates BatchSubprotocol and allows PublishBatch. Each
	// contained change retains its own Dot; v1 remains the default.
	EnableBatches   bool
	MaxBatchChanges int
	// EnableAwareness requires the opt-in crdt-sync-v3 subprotocol. OnAwareness
	// receives only authenticated, bounded, transient messages; applications
	// should apply them to their own awareness.Store rather than a CRDT inbox.
	EnableAwareness  bool
	AwarenessOptions awareness.Options
	OnAwareness      func(awareness.Update) error
	HandshakeTimeout time.Duration
	WriteTimeout     time.Duration
	OnChange         func(replica.Change) error
}

ClientConfig configures one reference-provider client. OnChange must pass each change to an application-owned, manifest-compatible replica.Inbox (or another equally durable delivery boundary).

type Config

type Config struct {
	Groups             []*Group
	Authenticate       Authenticate
	Authorize          Authorize
	AuthorizeAwareness AuthorizeAwareness
	OriginPatterns     []string
	MaxMessageBytes    int
	MaxActorBytes      int
	MaxQueuedMessages  int
	MaxBatchChanges    int
	HandshakeTimeout   time.Duration
	WriteTimeout       time.Duration
}

Config configures a Handler. Authentication and authorization are required; callers must not rely on the CRDT frame checksum as an identity check.

type Group

type Group struct {
	// contains filtered or unexported fields
}

Group owns a manifest-bound, bounded replica inbox and the live peers for that group. It has no operation log or snapshot store.

func NewGroup

func NewGroup(config GroupConfig) (*Group, error)

NewGroup creates one manifest-bound in-memory receiver. Apply must use the concrete CRDT decoder with limits appropriate to the application, then apply the decoded delta without a partial update on error.

func (*Group) Awareness added in v1.0.24

func (g *Group) Awareness() []awareness.Update

Awareness returns current non-expired awareness states. The returned data is a snapshot, not durable replication state.

func (*Group) Frontier

func (g *Group) Frontier() replica.Frontier

Frontier returns a copy of g's installed contiguous delivery frontier.

func (*Group) Manifest

func (g *Group) Manifest() replica.Manifest

Manifest returns the immutable-by-convention manifest negotiated by g.

func (*Group) Pending

func (g *Group) Pending() (changes, bytes int)

Pending reports the number and bytes of out-of-order changes retained by g.

type GroupConfig

type GroupConfig struct {
	Manifest          replica.Manifest
	Frontier          replica.Frontier
	Policy            crdt.ProtocolPolicy
	MaxPendingChanges int
	MaxPendingBytes   int
	Apply             replica.ApplyDelta
	// Awareness is an optional in-memory, short-lived store. Do not restore it
	// from a CRDT checkpoint; clean disconnects should publish a removal and
	// broken connections naturally disappear after its TTL.
	Awareness *awareness.Store
}

GroupConfig describes one in-memory replication group at the reference provider. Frontier must come from the same durable transaction as the application CRDT state when a production application restores a group.

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler implements an authenticated WebSocket endpoint for a fixed set of manifest-bound Groups.

func NewHandler

func NewHandler(config Config) (*Handler, error)

NewHandler validates a reference provider configuration. The returned handler rejects cross-origin requests unless OriginPatterns explicitly authorizes their origin host.

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(writer http.ResponseWriter, request *http.Request)

ServeHTTP authenticates the HTTP request, upgrades it, requires the provider subprotocol, and accepts changes only after an exact manifest handshake.

type Peer

type Peer struct {
	ID string
}

Peer is the authenticated identity returned by Authenticate. ID should be a stable application identity, not an unauthenticated user-supplied actor ID.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL