websocket

package
v2.0.0 Latest Latest
Warning

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

Go to latest
Published: Sep 11, 2026 License: AGPL-3.0 Imports: 12 Imported by: 0

Documentation

Overview

Package websocket is a WebSocket-backed AsyncNotifier that holds its client connections in process memory.

This provider is correct at one replica

Connections live in this process, so Publish reaches only the clients connected to this instance. Run two replicas behind a load balancer and a client connected to replica A never sees an event published on replica B. It fails as a missing notification rather than an error: nothing here detects the second instance, and nothing reports the events it did not receive.

That is a constraint on the deployment, not a tuning knob. A service that scales out wants the ably or pusher provider instead, where a hosted broker holds the connections and every replica publishes through it.

Why there is no messagequeue backplane

Fanning these events out over messagequeue was considered and rejected.

Such a backplane has to carry every event, including the ones bound for clients on the replica that published: delivering locally *and* over the queue would deliver twice to anyone connected here. So the broker's delivery guarantee becomes this provider's guarantee. Redis pub/sub is the only broker anyone would stand up for notification fanout, and it is at-most-once (see messagequeue's Consumer docs) — which would make the single-replica case, the one that works correctly today, less reliable than it is now. The multi-replica case it would fix already has two working answers above.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNilConfig = errors.New("websocket async notifier config is nil")
)

Functions

This section is empty.

Types

type Config

type Config struct {
	HeartbeatInterval time.Duration `env:"HEARTBEAT_INTERVAL" json:"heartbeatInterval,omitempty" yaml:"heartbeatInterval,omitempty"`
	ReadBufferSize    int           `env:"READ_BUFFER_SIZE"   json:"readBufferSize,omitempty"    yaml:"readBufferSize,omitempty"`
	WriteBufferSize   int           `env:"WRITE_BUFFER_SIZE"  json:"writeBufferSize,omitempty"   yaml:"writeBufferSize,omitempty"`
}

Config holds WebSocket async notifier configuration.

func (*Config) ValidateWithContext

func (cfg *Config) ValidateWithContext(ctx context.Context) error

ValidateWithContext validates a Config struct.

type Notifier

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

Notifier is a WebSocket-backed AsyncNotifier that manages direct client connections.

func NewNotifier

func NewNotifier(cfg *Config, opts ...Option) (*Notifier, error)

NewNotifier creates a new WebSocket-backed AsyncNotifier.

func (*Notifier) AcceptConnection

func (n *Notifier) AcceptConnection(w http.ResponseWriter, r *http.Request, channel, memberID string) error

AcceptConnection upgrades the HTTP connection to a WebSocket and registers it under the given channel and memberID.

func (*Notifier) Close

func (n *Notifier) Close() error

Close releases resources held by the notifier.

func (*Notifier) Publish

func (n *Notifier) Publish(ctx context.Context, channel string, event *async.Event) error

Publish sends an event to all connected clients on the given channel.

One client's failure does not stop the others: every connection on the channel is attempted, and the joined per-client failures come back from here, so a non-nil error means the event reached a subset of the channel.

type Option

type Option func(*options)

Option configures the Notifier this package constructs. The zero configuration works: absent observability deps are normalized downstream.

func WithLogger

func WithLogger(logger logging.Logger) Option

WithLogger attaches a logger.

func WithTracerProvider

func WithTracerProvider(tracerProvider tracing.Provider) Option

WithTracerProvider attaches a tracer provider.

Jump to

Keyboard shortcuts

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