pubsub

package
v0.13.1 Latest Latest
Warning

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

Go to latest
Published: Aug 6, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Index

Constants

View Source
const CName = "common.commonspace.pubsub"

Variables

View Source
var (
	ErrClosed = errors.New("pubsub service closed")
)

Functions

func RegisterRpc

func RegisterRpc(mux drpc.Mux, s Service) error

RegisterRpc registers the pubsub DRPC service on the given mux.

func TopicOwner

func TopicOwner(topic string) string

TopicOwner returns the account id that exclusively may publish to the topic, or "" if the topic is not in the self-owned acc/ namespace. The owner is the last segment. Assumes a validated fully-qualified topic.

func ValidatePattern

func ValidatePattern(pattern string) error

ValidatePattern checks a subscription pattern: canonical form, wildcards only as whole segments, '>' only in tail position.

func ValidateTopic

func ValidateTopic(topic string) error

ValidateTopic checks a fully-qualified publish topic: canonical form, no wildcards.

Types

type Config

type Config struct {
	MaxPayloadSize       int
	MaxPatternsPerStream int
	MaxPatternsPerSpace  int
	PublishRps           float64
	PublishBurst         int
	WriteQueueSize       int
	DispatchQueueSize    int
	DedupSize            int
	// MaxTimestampSkew bounds how stale (or future) a received message's timestamp
	// may be before it is dropped, raising the replay bar even after dedup eviction.
	MaxTimestampSkew time.Duration
	// ResyncInterval is how often a client re-pushes its interest to space peers,
	// keeping server-side interest alive across reconnects.
	ResyncInterval time.Duration
	// PeerTTL keeps a pubsub stream's peer from being reaped by idle pool GC.
	PeerTTL time.Duration
	// DialQueueWorkers/DialQueueSize size the pool's outbound dial pool.
	DialQueueWorkers int
	DialQueueSize    int
}

Config bounds the engine per DESIGN.md §9; zero values take defaults.

type Crypto

type Crypto interface {
	// Encrypt returns the key id used and the ciphertext.
	Encrypt(spaceId string, payload []byte) (keyId string, encrypted []byte, err error)
	// Decrypt resolves keyId to a historical read key and decrypts.
	Decrypt(spaceId, keyId string, encrypted []byte) ([]byte, error)
}

Crypto encrypts and decrypts payloads with the space read key. A nil Crypto means plaintext payloads (keyless spaces).

type Deps

type Deps struct {
	Membership MembershipChecker
	Crypto     Crypto
	Peers      PeerProvider // client side; may be nil on nodes
	Relay      Relay        // node side; nil on clients
	OnStatus   StatusHandler
	// Metric, if set, registers the private pool's prometheus metrics so a node
	// relaying at scale is observable. Optional.
	Metric metric.Metric
	Config Config
}

Deps carries the pluggable pieces wired by the node or client host.

type Handler

type Handler func(spaceId, topic string, identity crypto.PubKey, payload []byte)

Handler receives a decrypted, signature-verified message on a subscribed topic. Handlers run on a bounded dispatch queue and must not block.

type MembershipChecker

type MembershipChecker interface {
	CheckMember(ctx context.Context, spaceId string, identity crypto.PubKey) error
}

MembershipChecker gates subscribe and publish on space membership. Implementations resolve the space's ACL state; any non-nil error rejects.

type PeerProvider

type PeerProvider interface {
	SpacePeers(ctx context.Context, spaceId string) ([]peer.Peer, error)
}

PeerProvider resolves the peers a client sends publishes and interest to for a space: the responsible sync node plus any directly connected LAN peers.

type Relay

type Relay interface {
	// IsResponsible reports whether this node is responsible for the space.
	IsResponsible(spaceId string) bool
	// IsResponsibleNode reports whether peerId is a responsible node for the space
	// (used to authorize inbound relayed publishes).
	IsResponsibleNode(spaceId, peerId string) bool
	// OtherResponsiblePeers returns the other responsible nodes, excluding self.
	OtherResponsiblePeers(ctx context.Context, spaceId string) ([]peer.Peer, error)
}

Relay is implemented only on responsible nodes; nil on clients.

type Service

type Service interface {
	app.ComponentRunnable
	// Publish encrypts, signs and fire-and-forgets payload to the topic within the space.
	Publish(ctx context.Context, spaceId, topic string, payload []byte) error
	// Subscribe registers a local handler for a pattern and pushes the interest to
	// the space's peers. The returned func unregisters and unsubscribes.
	Subscribe(spaceId, pattern string, h Handler) (unsubscribe func(), err error)
	// SyncInterest (re)sends all local interest for the space to its current peers;
	// call after (re)connecting to a space's peers.
	SyncInterest(ctx context.Context, spaceId string) error
	// CloseSpace drops all local and serving-side interest for the space and
	// withdraws the local interest from its peers. Hosts call it on space
	// unload/close so a global service doesn't retain closed-space state.
	CloseSpace(spaceId string)
	// EvictMember drops all serving-side interest of an identity in a space,
	// enforcing DESIGN §6.4 (active drop on ACL removal). Nodes wire it to their
	// ACL-update hook. No-op on clients (they hold no serving interest).
	EvictMember(spaceId string, identity crypto.PubKey)
	// RevalidateMembers evicts every subscriber of the space whose account no
	// longer passes isMember. Nodes call it on an ACL change to cut off all
	// removed members in one pass. No-op on clients.
	RevalidateMembers(spaceId string, isMember func(account string) bool)
	// HandleStream serves an inbound PubSubStream; blocks for the stream lifetime.
	HandleStream(stream drpc.Stream) error
}

Service is the shared pubsub engine used by nodes (relay role, Deps.Relay set) and clients (Deps.Peers set) alike. One long-lived PubSubStream per peer pair multiplexes all spaces and topics; interest and routing state are in-memory only and die with the streams.

func New

func New(deps Deps) Service

type StatusHandler

type StatusHandler func(peerId string, status *pubsubproto.Status)

StatusHandler observes Status frames received from serving peers (rejections).

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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