realtime

package
v0.2.10 Latest Latest
Warning

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

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

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BuildEventPublisher

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

BuildEventPublisher adapts PubSub to the builder.EventPublisher interface.

func NewBuildEventPublisher

func NewBuildEventPublisher(ps *PubSub, hub *Hub) *BuildEventPublisher

NewBuildEventPublisher creates a BuildEventPublisher.

func (*BuildEventPublisher) PublishBuildEvent

func (p *BuildEventPublisher) PublishBuildEvent(ctx context.Context, agentID, buildID uuid.UUID, status, errMsg string)

PublishBuildEvent publishes an agent build lifecycle event.

func (*BuildEventPublisher) PublishBuildLogLine

func (p *BuildEventPublisher) PublishBuildLogLine(ctx context.Context, agentID, buildID uuid.UUID, seq int64, stream, line string)

PublishBuildLogLine publishes a single build log line for real-time streaming. seq is a monotonic counter per build (across both sol and docker streams); the frontend uses it to dedupe against a REST snapshot of the persisted log.

type Conn

type Conn struct {
	ID     string
	UserID uuid.UUID
	Email  string
	// contains filtered or unexported fields
}

Conn wraps a WebSocket connection with user identity and a send buffer.

func NewConn

func NewConn(ws *websocket.Conn, userID uuid.UUID, email string, logger *zap.Logger) *Conn

NewConn creates a new Conn for the given WebSocket and user.

func (*Conn) Close

func (c *Conn) Close()

Close closes the send channel, causing WritePump to exit.

func (*Conn) ReadPump

func (c *Conn) ReadPump(ctx context.Context, handler MessageHandler)

ReadPump reads messages from the WebSocket and dispatches to handler. Blocks until the connection closes or ctx is cancelled.

func (*Conn) Send

func (c *Conn) Send(data []byte)

Send enqueues a message for writing. Non-blocking: drops if buffer full.

func (*Conn) SendEnvelope

func (c *Conn) SendEnvelope(env Envelope)

SendEnvelope marshals and enqueues an envelope.

func (*Conn) WritePump

func (c *Conn) WritePump(ctx context.Context)

WritePump drains the send channel and writes to the WebSocket. Also sends periodic pings for liveness detection. Blocks until the send channel is closed or ctx is cancelled.

type Envelope

type Envelope struct {
	Type      string          `json:"type"`
	RequestID string          `json:"requestId,omitempty"`
	TopicID   string          `json:"topicId,omitempty"`
	Payload   json.RawMessage `json:"payload,omitempty"`
}

Envelope is the JSON wire format for all WebSocket messages.

func NewEnvelope

func NewEnvelope(eventType, topicID string, payload proto.Message) Envelope

NewEnvelope creates an Envelope, marshaling the payload via protojson. The proto.Message constraint provides compile-time enforcement — passing map[string]any or dbq types is a compile error.

type Handler

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

Handler routes inbound WebSocket messages. Subscriptions are no longer client-initiated — the WS upgrade handler auto-subscribes new connections to every agent the user is a member of, based on durable agent_members state. Any inbound message from the client is therefore unexpected; we log and reject so misbehaving clients don't silently drift.

func NewHandler

func NewHandler(database *db.DB, hub *Hub, pubsub *PubSub, logger *zap.Logger) *Handler

NewHandler creates a new inbound message handler.

func (*Handler) HandleMessage

func (h *Handler) HandleMessage(conn *Conn, env Envelope)

HandleMessage rejects all inbound messages. The WS is server→client only.

type Hub

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

Hub manages WebSocket connections and topic subscriptions. A single connection can be subscribed to many topics at once — typically every agent the user is a member of, wired up at WS-accept time.

func NewHub

func NewHub(logger *zap.Logger) *Hub

NewHub creates a new Hub.

func (*Hub) BroadcastToTopic

func (h *Hub) BroadcastToTopic(topicID uuid.UUID, env Envelope)

BroadcastToTopic sends an envelope to all connections subscribed to a topic. Events are also buffered per topic so late subscribers can replay missed events.

func (*Hub) ClearTopicBuffer

func (h *Hub) ClearTopicBuffer(topicID uuid.UUID)

ClearTopicBuffer removes the replay buffer for a topic. Called after a terminal event (build complete/failed) since replay is no longer needed.

func (*Hub) ConnCount

func (h *Hub) ConnCount() int

ConnCount returns the number of active connections.

func (*Hub) OnTopicSubscriptionChange

func (h *Hub) OnTopicSubscriptionChange(onFirst func(uuid.UUID), onLast func(uuid.UUID))

OnTopicSubscriptionChange sets callbacks for when the first local connection subscribes to a topic and when the last unsubscribes. Used by PubSub to manage Redis subscriptions.

func (*Hub) Register

func (h *Hub) Register(conn *Conn)

Register adds a connection to the hub.

func (*Hub) SendToConnection

func (h *Hub) SendToConnection(connID string, env Envelope)

SendToConnection sends an envelope to a specific connection by ID.

func (*Hub) Subscribe

func (h *Hub) Subscribe(conn *Conn, topicID uuid.UUID)

Subscribe adds the connection to the given topic if not already subscribed. Pre-existing topic subscriptions on this connection are not affected — Subscribe is additive, so the WS accept handler can call it in a loop over the user's member agents without disturbing anything else. Replays any buffered events for the topic to the newly-subscribed connection.

func (*Hub) TopicConnCount

func (h *Hub) TopicConnCount(topicID uuid.UUID) int

TopicConnCount returns the number of connections subscribed to a topic.

func (*Hub) Unregister

func (h *Hub) Unregister(conn *Conn)

Unregister removes a connection and all its topic subscriptions, firing onLastUnsubscribe for any topic that's now empty.

type MessageHandler

type MessageHandler func(conn *Conn, env Envelope)

MessageHandler processes an inbound WebSocket message from a client.

type PubSub

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

PubSub delivers real-time envelopes to local WebSocket subscribers via the Hub. This is the single-instance implementation. For multi-instance fan-out (e.g. via Redis pub/sub), replace or extend this with a cross-process transport.

func NewPubSub

func NewPubSub(hub *Hub, logger *zap.Logger) *PubSub

NewPubSub creates a PubSub wired to the given Hub.

func (*PubSub) ClearTopicBuffer

func (ps *PubSub) ClearTopicBuffer(topicID uuid.UUID)

ClearTopicBuffer removes the replay buffer for a topic. Call after terminal events (run complete, build complete) so reconnecting clients don't replay stale streaming events.

func (*PubSub) Close

func (ps *PubSub) Close()

Close is a no-op for the local implementation.

func (*PubSub) Publish

func (ps *PubSub) Publish(ctx context.Context, topicID uuid.UUID, env Envelope) error

Publish delivers an envelope to all local subscribers of the topic.

Jump to

Keyboard shortcuts

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