Help us shape the future of Go! Take the 2026 Go Developer Survey

hub

package
v2.3.0 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2026 License: Apache-2.0 Imports: 3 Imported by: 0

Documentation

Overview

Package hub carries memory events to connected clients: a search hit, a change to an item, a metrics snapshot. Each Hub is an instance, so a host owns the lifetime of its hub and nothing is shared between processes' hubs or tests. What carries an event to the other replicas of a host is a Transport the host passes in; with none, the hub is local.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ChangeEvent

type ChangeEvent struct {
	Op string `json:"op"` // "upsert" | "delete"
	// Item is set for an upsert. It is typed any so a host can send the shape its
	// own API already uses for an item without this package knowing it.
	Item any `json:"item,omitempty"`
	// ID is set for a delete, and Kind is the deleted item's kind: a delete has
	// nothing else on the wire, and a client cannot tell which category region a
	// deleted item belonged to without it.
	ID   string `json:"id,omitempty"`
	Kind string `json:"kind,omitempty"`
}

ChangeEvent reports that an item was created, updated or deleted.

type Frame

type Frame struct {
	Type FrameType       `json:"type"`
	Data json.RawMessage `json:"data"`
}

Frame is the one envelope every subscriber receives: {"type": "hit"|"change"|"metrics", "data": <payload>}. Data is marshalled once per event, so every subscriber decodes it independently.

type FrameType

type FrameType string

FrameType is the envelope's explicit discriminator.

const (
	// FrameHit marks a Frame whose Data is a HitEvent.
	FrameHit FrameType = "hit"
	// FrameChange marks a Frame whose Data is a ChangeEvent.
	FrameChange FrameType = "change"
	// FrameMetrics marks a Frame whose Data is whatever PublishMetrics was given.
	FrameMetrics FrameType = "metrics"
)

type HitEvent

type HitEvent struct {
	ItemIDs []string `json:"itemIds"`
	Query   string   `json:"query"`
	// Kind is the search's kind filter, usually empty: not a per-item kind.
	Kind string `json:"kind,omitempty"`
	// Kinds is the kind of each item, parallel to ItemIDs, so a client can place
	// a hit by category without having the item itself. A client that finds it
	// absent or shorter than ItemIDs must fall back to behaviour that needs no
	// kind.
	Kinds []string `json:"kinds,omitempty"`
}

HitEvent reports that a search surfaced items a downstream consumer used.

type Hub

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

Hub fans events out to subscribers. Each subscriber channel is buffered and written to without blocking: a slow client drops frames rather than stalling a publisher.

func New

func New(transport Transport) *Hub

New builds a hub. transport may be nil.

func (*Hub) ApplyRemoteChange

func (h *Hub) ApplyRemoteChange(evt ChangeEvent)

ApplyRemoteChange applies a change received from a peer: the same broadcast as PublishChange, without handing it to the transport.

func (*Hub) ApplyRemoteHit

func (h *Hub) ApplyRemoteHit(evt HitEvent)

ApplyRemoteHit applies a hit received from a peer: the same local effects as PublishHit, without handing it to the transport.

func (*Hub) ClientCount

func (h *Hub) ClientCount() int

ClientCount is the number of subscribers on this hub. A sampler that only matters when someone listens can gate on it.

func (*Hub) HitCount

func (h *Hub) HitCount(id string) int64

HitCount is how many times the item was surfaced by a search.

func (*Hub) PublishChange

func (h *Hub) PublishChange(evt ChangeEvent)

PublishChange broadcasts a locally originated change to every subscriber, then hands it to the transport. Use it for shared items only.

func (*Hub) PublishChangeTo

func (h *Hub) PublishChangeTo(userHash string, evt ChangeEvent)

PublishChangeTo sends a change only to the subscribers owned by userHash: the channel for private items, whose content must not reach other users. With no userHash (no authentication) it broadcasts, so the single local user still sees live updates. It is never handed to the transport: the event carries no owner, so a peer applying it could only broadcast it.

func (*Hub) PublishHit

func (h *Hub) PublishHit(evt HitEvent)

PublishHit broadcasts a locally originated hit, counts it per item, then hands it to the transport.

func (*Hub) PublishMetrics

func (h *Hub) PublishMetrics(v any)

PublishMetrics broadcasts a metrics snapshot to this hub's subscribers. It is local by design: the numbers are one process's view, and forwarding them would mix one replica's counters into another's stream.

func (*Hub) Subscribe

func (h *Hub) Subscribe(userHash string) (<-chan Frame, func())

Subscribe registers a subscriber and returns its channel and a function that removes it and closes the channel; call that function exactly once. userHash scopes delivery of PublishChangeTo to that owner; "" is an anonymous subscription that receives only broadcasts.

type Transport

type Transport interface {
	PublishHit(HitEvent)
	PublishChange(ChangeEvent)
}

Transport carries a locally originated event to the other replicas of a host. Hub calls it after the local effects of PublishHit and PublishChange, and never for an event applied from a peer (ApplyRemoteHit, ApplyRemoteChange) or for a change scoped to one user (PublishChangeTo), so a mesh built on top of it cannot loop an event back and forth. Implementations must not block.

Jump to

Keyboard shortcuts

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