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 ¶
- type ChangeEvent
- type Frame
- type FrameType
- type HitEvent
- type Hub
- func (h *Hub) ApplyRemoteChange(evt ChangeEvent)
- func (h *Hub) ApplyRemoteHit(evt HitEvent)
- func (h *Hub) ClientCount() int
- func (h *Hub) HitCount(id string) int64
- func (h *Hub) PublishChange(evt ChangeEvent)
- func (h *Hub) PublishChangeTo(userHash string, evt ChangeEvent)
- func (h *Hub) PublishHit(evt HitEvent)
- func (h *Hub) PublishMetrics(v any)
- func (h *Hub) Subscribe(userHash string) (<-chan Frame, func())
- type Transport
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 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 (*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 ¶
ApplyRemoteHit applies a hit received from a peer: the same local effects as PublishHit, without handing it to the transport.
func (*Hub) ClientCount ¶
ClientCount is the number of subscribers on this hub. A sampler that only matters when someone listens can gate on it.
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 ¶
PublishHit broadcasts a locally originated hit, counts it per item, then hands it to the transport.
func (*Hub) PublishMetrics ¶
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.
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.