Subjects and patterns¶
A subject is dot-separated tokens. a.b.c.
| Token | Matches |
|---|---|
| a literal | itself, case sensitively |
* |
exactly one token, in any position |
> |
one or more tokens, and only as the final token |
An empty token makes a subject invalid, and an invalid subject matches nothing.
func Match(pattern, subject string) bool
func ValidatePattern(pattern string) error // may this be subscribed to
func ValidateSubject(subject string) error // may this be published to
The rules are implemented, not approximated¶
| Pattern | Subject | Match | Why |
|---|---|---|---|
a.* |
a.b.c |
no | * is exactly one token, never a tail |
* |
a.b |
no | same |
a.> |
a.b.c.d |
yes | > is a tail |
a.> |
a |
no | the tail must match at least one token |
> |
a.b.c |
yes | a bare tail matches everything valid |
a.*.c |
a..c |
no | the empty token makes the subject invalid |
a.B.c |
a.b.c |
no | case sensitive |
Those rows are from a truth table run three ways: against a real NATS server, against a matcher written from the documented rules, and against a prefix-and-glob approximation. The first two agreed on all 21 rows. The approximation disagreed on 6, in both directions.
So portability is real, and it is not free: it requires implementing the token rules rather than approximating them.
Validation refuses more than NATS does¶
Deliberately, and both cases it adds are silent failures.
| Pattern | What NATS does | What this module does |
|---|---|---|
a..b, a.b., .a.b, a b, "" |
refuses cleanly | refuses |
a.**, a.>> |
accepts | refuses |
a.>.c |
closes the connection | refuses |
a.** is accepted by NATS and can never match, because no token will ever equal **. That is a
consumer receiving nothing for ever, with no error anywhere — the exact failure this module exists to
eliminate.
a.>.c is not caught client-side at all. It reaches the server, which terminates the connection, so
every other subscription on it dies too. One malformed pattern takes down the whole bus.
Validation is therefore this module's own guarantee rather than a backend feature being forwarded, which is why an invalid pattern is fatal at construction rather than degrading.
The limit¶
This pattern language is NATS-shaped. A backend with a flat namespace and no wildcard subscription,
Kafka topics or SQS, cannot offer it. It reports Capabilities.Patterns: false, and a subscription that
asks for a wildcard pattern there is refused at construction, fatally, rather than degraded: a
pattern that silently matched only itself would be the exact silent failure this module exists to
eliminate. Portable among backends that have a pattern language; not universal.