nats-io / nats-architecture-and-design

Architecture and Design Docs
Apache License 2.0
196 stars 21 forks source link

Subscription Filter Subject Matching #67

Open scottf opened 2 years ago

scottf commented 2 years ago

Overview

Ensure filter subject matching when creating subscriptions is consistent. Filter subject matching is required when a subscription is requested against an existing durable.

Glossary

SubscribeSubject - The subject used in the api call for subscription. FilterSubject - The filter subject as set in the existing consumer. null, empty, undefined and '>' are all identical StreamSubject - The subject for the corresponding stream. Is null/empty/undefined when the stream contains more than 1 subject and therefore cannot match.

Clients and Tools

Implementation Example

isFilterMatch(subscribeSubject string, filterSubject string, streamName string) returns boolean 
{
    // subscribeSubject guaranteed to not be null / empty / undefined
    // filterSubject may be null / empty / undefined or have value

    if (subscribeSubject is exactly equal to filterSubject) {
        return true
    }

    if (filterSubject is null or empty or undefined or equals ">") {
        // lookup stream subject returns null if there is not exactly one subject
        streamSubject = lookupStreamSubject(streamName)
        return (subscribeSubject is exactly equal to streamSubject)
    }

    return false
}
lookupStreamSubject(streamName string) returns string may be null / empty / undefined
{
    1. get StreamInfo for stream name
    2. if stream has more than 1 subject return null / empty / undefined
    3. else return the one subject
}

Unit Tests

  1. Create a stream with the Stream Subject(s)
  2. Create a push durable with the Filter Subject
  3. Try to subscribe with the Subscribe Subject + durable name (not bind)
Stream Subject(s) Filter Subject Subscribe Subject Match Notes
foo, bar one subject
foo foo Yes FS equals SS
">" ">" Yes "
"*" "*" Yes "
"" foo Yes SS != empty FS, but stream has exactly 1 subject and is a match.
">" foo Yes SS != FS of '>' but stream has exactly 1 subject and '>' matches.
"*" foo No
foo, bar multiple subjects no wildcards
foo foo Yes FS equals SS
">" ">" Yes "
"*" "*" Yes "
"" foo No
">" foo No
"*" foo No
foo.> multiple subjects via '>'
foo.A foo.A Yes FS equals SS
">" ">" Yes FS equals SS
"" foo.A No
">" foo.A No
foo_GT foo.A No
foo.* multiple subjects via '*'
foo.A foo.A Yes FS equals SS
">" ">" Yes FS equals SS
"" foo.A No
">" foo.A No
foo_STAR foo.A No

Other Tasks

Client authors please update with your progress. If you open issues in your own repositories as a result of this request, please link them to this one by pasting the issue URL in a comment or main issue description.

marthaCP commented 1 year ago

This will be a non-issue in JS Simplification.