[eval] [FIXED] Fix subject tree intersection to match literals when followed by additional wildcards#1
Open
Uzay-G wants to merge 2 commits intoeval/base-pr-6827from
Open
[eval] [FIXED] Fix subject tree intersection to match literals when followed by additional wildcards#1Uzay-G wants to merge 2 commits intoeval/base-pr-6827from
Uzay-G wants to merge 2 commits intoeval/base-pr-6827from
Conversation
…tional wildcards Signed-off-by: Neil Twigg <neil@nats.io>
Signed-off-by: Maurice van Veen <github@mauricevanveen.com>
|
Review started. |
There was a problem hiding this comment.
All checks passed.
Expected behavior
- A JetStream consumer with filter subjects
["stream.A", "stream.A.>"]delivers all messages onstream.A(the literal) andstream.A.*/stream.A.>(the wildcard children) - The
IntersectStreefunction finds literal subject matches even when the sublist level also contains wildcard (fwc/pwc) children - No duplicate messages are delivered when filter subjects overlap structurally (literal + extended wildcard at the same prefix)
- Existing sublist intersection behavior (literals, PWC, FWC, overlapping patterns) is preserved without regressions
What happens
- ✅ Happy path works: consumer with
["stream.A", "stream.A.>"]delivers all 10 messages onstream.Aand all 8 messages on child subjects, with no duplicates (18 total) - ✅ Bug confirmed on pre-fix build: same consumer shows 0 unprocessed messages on the old code, proving the fix resolves the issue
- ✅ No duplicates: consumer pending count matches exactly the number of published messages across all tested patterns (
["stream.A", "stream.A.>"],["stream.A", "stream.A.>", "stream.B"],["stream.A", "stream.B"]) - ✅ Real-time delivery works: messages published after consumer creation are also correctly delivered through overlapping filters
- ✅ All 61 sublist tests and the new
TestJetStreamConsumerDeliverAllOverlappingFilterSubjectstest pass with no regressions
Detailed evidence
Setup
export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin
# Build the fixed server
go build -o /home/agent/nats-server/nats-server .
# → nats-server: v2.11.2-RC.2
# Build the pre-fix server for comparison
git checkout 82cb3edb0^ -- server/sublist.go
go build -o /tmp/nats-server-old .
git checkout HEAD -- server/sublist.goDemo 1: Happy path — overlapping literal + FWC filters
# Start fixed server with JetStream
/home/agent/nats-server/nats-server -js -sd /tmp/nats-data -p 4222 &
# Create stream
nats stream add TEST --subjects "stream.>" --storage memory ...
# → Stream TEST was created
# Publish 10 messages to stream.A
for i in $(seq 1 10); do nats pub stream.A "message-$i"; done
# Create consumer with overlapping filter subjects
nats consumer add TEST OVERLAP_CONSUMER \
--deliver all \
--filter "stream.A" --filter "stream.A.>" \
--ack explicit --pull --defaults
# → Unprocessed Messages: 10 ← correct, all 10 found
# Fetch all messages
nats consumer next TEST OVERLAP_CONSUMER --count 10 --timeout 5s
# → 10 messages received on stream.A, cons seq 1-10, str seq 1-10Demo 2: Child subject delivery via FWC
# Publish to child subjects
for i in $(seq 1 5); do nats pub stream.A.child "child-msg-$i"; done
for i in $(seq 1 3); do nats pub stream.A.deep.nested "deep-msg-$i"; done
# Fetch from consumer
nats consumer next TEST OVERLAP_CONSUMER --count 10 --timeout 5s
# → 8 messages received: 5 on stream.A.child (cons seq 11-15), 3 on stream.A.deep.nested (cons seq 16-18)Demo 3: No duplicates
# Create new consumer with ack=none to verify total count
nats consumer add TEST DEDUP_CHECK \
--deliver all \
--filter "stream.A" --filter "stream.A.>" \
--ack none --pull --defaults
# → Unprocessed Messages: 18 ← exactly 10+5+3, no duplicates
# Fetch and verify unique stream sequences
nats consumer next TEST DEDUP_CHECK --count 20 --timeout 5s | grep "subj:" | sort
# → 18 lines, each with unique str seq 1-18Demo 4: Bug confirmed on pre-fix build
# Start OLD server (built from parent commit before fix)
pkill -9 nats-server
/tmp/nats-server-old -js -sd /tmp/nats-data-old -p 4222 &
# Same setup: create stream, publish 10 messages to stream.A
nats stream add TEST --subjects "stream.>" --storage memory ...
for i in $(seq 1 10); do nats pub stream.A "message-$i"; done
# Create same consumer
nats consumer add TEST BUG_CHECK \
--deliver all \
--filter "stream.A" --filter "stream.A.>" \
--ack none --pull --defaults
# → Unprocessed Messages: 0 ← BUG: should be 10, but the old intersection misses the literalDemo 5: Mixed complex filters
# Restart fixed server, create stream, publish various messages
# stream.A (literal) + stream.A.> (fwc) + stream.B (literal)
nats consumer add TEST MIXED_COMPLEX \
--deliver all \
--filter "stream.A" --filter "stream.A.>" --filter "stream.B" \
--ack none --pull --defaults
# → Unprocessed Messages: 19 ← 10+5+3+1, correct
# Overlapping PWC+literal correctly rejected by server
nats consumer add TEST PWC_LITERAL \
--filter "stream.*" --filter "stream.A" ...
# → error: consumer subject filters cannot overlap (10138)Demo 6: Real-time delivery
# Fresh server, create consumer FIRST, then publish
nats consumer add TEST PUSH_OVERLAP \
--deliver all \
--filter "stream.A" --filter "stream.A.>" \
--ack explicit --pull --defaults
# → Unprocessed Messages: 0
# Publish after consumer creation
for i in $(seq 1 5); do nats pub stream.A "realtime-$i"; done
for i in $(seq 1 3); do nats pub stream.A.child "realtime-child-$i"; done
nats consumer info TEST PUSH_OVERLAP | grep Unprocessed
# → Unprocessed Messages: 8
nats consumer next TEST PUSH_OVERLAP --count 10 --timeout 3s | grep "subj:"
# → 5 stream.A messages + 3 stream.A.child messages, all deliveredTest suite
# Sublist intersection tests (including new FWCExtended)
go test -v -run "TestSublistInterestBasedIntersection" ./server/
# → PASS (all 10 subtests)
# JetStream consumer overlapping filter test
go test -v -run "TestJetStreamConsumerDeliverAllOverlappingFilterSubjects" ./server/
# → PASS
# All sublist tests (regression check)
go test -v -run "TestSublist" ./server/
# → PASS (61 tests, 0.034s)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Mirror of nats-io#6827 (MERGED) for Orpheus review evaluation.
Upstream: nats-io#6827
Original PR description:
The subject tree intersection could miss non-wildcard matches if they were followed up by further extended wildcards in other sublist filters. This is now fixed.
Fixes nats-io#6824.
Signed-off-by: Neil Twigg neil@nats.io
Co-authored-by: Maurice van Veen github@mauricevanveen.com