Documentation
¶
Index ¶
- Constants
- Variables
- func Match(pattern, topic string) bool
- func NamespaceOf(channel string) (string, error)
- func SplitSegments(s string) []string
- func ValidateChannel(channel string) error
- func ValidateNamespace(ns string) error
- func ValidateTopic(topic string) error
- type Matcher
- type Subscriber
- type Subscription
Constants ¶
const NSDelimiter = ":"
NSDelimiter separates the namespace from the topic part of a namespaced channel ("acme:chat.room1"). It participates in segment splitting alongside delimiter ("."), so "acme:chat.room1" is the three segments [acme, chat, room1] and "acme:*" is a single-segment wildcard scoped to the "acme" namespace. Exactly one NSDelimiter is required: client-visible channels can therefore never collide with reserved identifiers that use ":" differently (e.g. Redis control keys).
Variables ¶
var ErrBadChannel = errors.New("channel does not fit the namespaced channel grammar")
ErrBadChannel is returned when a channel is rejected by ValidateChannel: it does not carry exactly one namespace delimiter, its namespace part is not a valid namespace identifier, or its topic part fails the structural topic rules (see ValidateTopic).
var ErrBadNamespace = errors.New("invalid namespace identifier")
ErrBadNamespace is returned when a namespace identifier is rejected: it is empty, longer than namespaceMaxLen, or contains characters outside [a-z0-9-] (leading/trailing "-" is also rejected).
var ErrBadSubscriber = errors.New("subscriber is not comparable")
ErrBadSubscriber is returned by Subscribe when sub cannot be used as a map key. Matcher implementations store subscribers in maps, so non-comparable values are rejected up front instead of panicking mid-operation.
var ErrBadTopic = errors.New("topic does not fit within topic space")
ErrBadTopic is returned when a topic is rejected: it is empty, contains explicit empty segments (e.g. "a.", ".a", "a..b"), contains "**" outside of the final segment (e.g. "a.**.b", "a**b"), or does not fit within the matcher's topic space.
Functions ¶
func Match ¶ added in v0.2.0
Match reports whether the subscription pattern matches the concrete topic. It is the exported form of matchCriteria — the single pattern-matching implementation shared by every caller (e.g. sessionCoversChannel); there is no second glob dialect.
func NamespaceOf ¶ added in v1.2.0
NamespaceOf returns the namespace part of a namespaced channel, or ErrBadChannel when the channel does not carry exactly one namespace delimiter with a valid namespace identifier.
func SplitSegments ¶ added in v1.2.0
SplitSegments splits a topic, pattern or channel into its segments. Both delimiter (".") and NSDelimiter (":") separate segments, so the namespaced channel "acme:chat.room1" is the three segments [acme, chat, room1]. Unlike strings.FieldsFunc, consecutive delimiters yield empty segments, preserving the invalid-topic detection in validTopic and matchCriteria.
func ValidateChannel ¶ added in v1.2.0
ValidateChannel validates a namespaced channel or subscription pattern: exactly one nsDelimiter, a valid namespace identifier before it, and a structurally valid topic after it (ValidateTopic rules; wildcards are allowed per those rules). It is the entry point for the session-plane namespace guard; ValidateTopic stays structure-only.
func ValidateNamespace ¶ added in v1.2.0
ValidateNamespace reports whether ns is a valid namespace identifier: 1-32 characters from [a-z0-9-], starting and ending with [a-z0-9].
func ValidateTopic ¶ added in v0.2.0
ValidateTopic reports whether topic is a valid channel or subscription pattern: a non-empty list of non-empty segments separated by "." or ":" with "**" allowed only as the final segment. It is the single structural validation entry point shared by the matchers, the hub's exact-subscription path and the broker publish paths; the namespace grammar (ValidateChannel) layers on top of it at the session boundary.
Types ¶
type Matcher ¶
type Matcher interface {
// Subscribe adds the Subscriber to the topic and returns a Subscription.
Subscribe(topic string, sub Subscriber) (*Subscription, error)
// Unsubscribe removes the Subscription. It is idempotent and safe to call
// with a nil Subscription.
Unsubscribe(sub *Subscription)
// Lookup returns the Subscribers for the given topic.
Lookup(topic string) []Subscriber
}
Matcher contains topic subscriptions and performs matches on them.
Topics are lists of non-empty segments separated by "." or ":" (e.g. "forex.eur", "acme:chat.room1", "*", "a.b.c"). The single segment "*" is a wildcard matching exactly one segment. The final segment "**" is a multi-segment wildcard matching zero or more segments (MQTT-style suffix wildcard): "a.**" matches "a", "a.b" and "a.b.c", and a bare "**" matches every topic. "**" anywhere else (middle position like "a.**.b" or embedded like "a**b") is rejected. The empty topic, topics with explicit empty segments ("a.", ".a", "a..b") and topics with middle-position "**" are rejected by Subscribe with ErrBadTopic and never match in Lookup. Segment count is significant for everything but a trailing "**": "a" does not match "a.b".
Duplicate subscription semantics differ between implementations:
- The naive, trie and cs-trie matchers are idempotent per (topic, Subscriber): subscribing the same subscriber to the same topic twice is a no-op, and one Unsubscribe removes it.
- The inverted and optimized inverted bitmap matchers are multi-subscription: every Subscribe call allocates a fresh position, so the same subscriber may subscribe to the same topic multiple times and each subscription must be removed with its own Unsubscribe.
Unsubscribe is idempotent: calling it twice with the same Subscription, or with a nil Subscription, is a no-op.
func NewCSTrieMatcher ¶
func NewCSTrieMatcher() Matcher
func NewNaiveMatcher ¶
func NewNaiveMatcher() Matcher
func NewTrieMatcher ¶
func NewTrieMatcher() Matcher
type Subscriber ¶
type Subscriber interface{}
Subscriber is a value associated with a subscription.
Subscribers must be comparable: implementations store them in maps and use them as keys. Non-comparable values are rejected by Subscribe with ErrBadSubscriber. A nil Subscriber is allowed.
type Subscription ¶
type Subscription struct {
ID uint32
Topic string
Subscriber Subscriber
}
Subscription represents a topic subscription.
ID is only meaningful for the bitmap implementations; the naive, trie and cs-trie implementations leave it at its zero value. A Subscription is only valid for the Matcher that created it.