[Issue #21] Add namespace event filtering #54

Merged
HugoNijhuis merged 1 commits from issue-21-namespace-event-filtering-v2 into main 2026-01-10 22:51:21 +00:00
Owner

Closes #21

Summary

Adds support for filtering events by type or actor pattern within namespace subscriptions for efficient event handling.

Changes

  • Add SubscriptionFilter type with EventTypes and ActorPattern fields
  • Add SubscribeWithFilter to EventBroadcaster interface
  • Implement filtering in EventBus preserving full wildcard pattern support
  • Implement filtering in NATSEventBus (server-side namespace filtering, client-side event/actor filters)
  • Add MatchActorPattern function for actor ID pattern matching
  • Add comprehensive unit tests for all filtering scenarios

Filter Syntax

Event Type Filter:

filter := &SubscriptionFilter{
    EventTypes: []string{"OrderPlaced", "OrderShipped"},
}

Actor Pattern Filter:

filter := &SubscriptionFilter{
    ActorPattern: "order-*",  // Matches order-123, order-456, etc.
}

Combined Filter (AND logic):

filter := &SubscriptionFilter{
    EventTypes: []string{"OrderPlaced"},
    ActorPattern: "order-*",
}
ch := bus.SubscribeWithFilter("orders", filter)

Acceptance Criteria

  • Support event type filters (e.g., only "OrderPlaced" events)
  • Support actor ID pattern filters (e.g., "order-*")
  • Filters applied server-side where possible (NATS subjects for namespaces)
  • Combine multiple filters (AND logic)
  • Document filter syntax

Notes

This is a v2 implementation that works with the existing wildcard subscription support (PR #52) and metrics (PR #49). The previous attempt (PR #51) was closed due to conflicts with those features.

Closes #21 ## Summary Adds support for filtering events by type or actor pattern within namespace subscriptions for efficient event handling. ## Changes - Add `SubscriptionFilter` type with `EventTypes` and `ActorPattern` fields - Add `SubscribeWithFilter` to `EventBroadcaster` interface - Implement filtering in `EventBus` preserving full wildcard pattern support - Implement filtering in `NATSEventBus` (server-side namespace filtering, client-side event/actor filters) - Add `MatchActorPattern` function for actor ID pattern matching - Add comprehensive unit tests for all filtering scenarios ## Filter Syntax **Event Type Filter:** ```go filter := &SubscriptionFilter{ EventTypes: []string{"OrderPlaced", "OrderShipped"}, } ``` **Actor Pattern Filter:** ```go filter := &SubscriptionFilter{ ActorPattern: "order-*", // Matches order-123, order-456, etc. } ``` **Combined Filter (AND logic):** ```go filter := &SubscriptionFilter{ EventTypes: []string{"OrderPlaced"}, ActorPattern: "order-*", } ch := bus.SubscribeWithFilter("orders", filter) ``` ## Acceptance Criteria - [x] Support event type filters (e.g., only "OrderPlaced" events) - [x] Support actor ID pattern filters (e.g., "order-*") - [x] Filters applied server-side where possible (NATS subjects for namespaces) - [x] Combine multiple filters (AND logic) - [x] Document filter syntax ## Notes This is a v2 implementation that works with the existing wildcard subscription support (PR #52) and metrics (PR #49). The previous attempt (PR #51) was closed due to conflicts with those features.
HugoNijhuis added 1 commit 2026-01-10 22:46:12 +00:00
Add namespace event filtering (SubscribeWithFilter)
All checks were successful
CI / build (pull_request) Successful in 19s
CI / build (push) Successful in 39s
ef73fb6bfd
Adds support for filtering events by type or actor pattern within namespace
subscriptions. Key changes:

- Add SubscriptionFilter type with EventTypes and ActorPattern fields
- Add SubscribeWithFilter to EventBroadcaster interface
- Implement filtering in EventBus with full wildcard pattern support preserved
- Implement filtering in NATSEventBus (server-side namespace, client-side filters)
- Add MatchActorPattern function for actor ID pattern matching
- Add comprehensive unit tests for all filtering scenarios

Filter Processing:
- EventTypes: Event must match at least one type in the list (OR within types)
- ActorPattern: Event's ActorID must match the pattern (supports * and > wildcards)
- Multiple filters are combined with AND logic

This implementation works alongside the existing wildcard subscription support:
- Namespace wildcards (* and >) work with event filters
- Filters are applied after namespace pattern matching
- Metrics are properly recorded for filtered subscriptions

Closes #21

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Author
Owner

AI Code Review

This is an automated review generated by the code-reviewer agent.

Summary

This PR successfully implements namespace event filtering via SubscribeWithFilter, enabling efficient event handling by filtering on event types and actor patterns. The implementation integrates cleanly with existing wildcard subscription support and metrics infrastructure. Code quality is excellent with comprehensive test coverage.

Findings

Code Quality

  • Excellent refactoring: The conversion from []chan *Event to []*filteredSubscription is cleanly executed throughout EventBus
  • Good abstraction: SubscriptionFilter encapsulates filtering logic with clear IsEmpty() and Matches() methods
  • Consistent pattern: MatchActorPattern follows the same wildcard semantics as MatchNamespacePattern (*, >)
  • Clean integration: Subscribe() delegates to SubscribeWithFilter(pattern, nil), reducing code duplication
  • Well-documented: Comprehensive godoc comments with examples for SubscribeWithFilter and SubscriptionFilter
  • Non-breaking change: Backward compatibility maintained - existing Subscribe() calls continue to work

Potential Bugs

  • No issues found: The AND logic for combined filters is correctly implemented
  • Nil handling: Filter nil checks are appropriate (nil or IsEmpty() means no filtering)
  • Edge cases covered: Empty patterns, nil events, and empty filters are all handled correctly in tests

Security Concerns

  • No security concerns identified: Filtering happens client-side as documented, which is appropriate
  • Wildcard considerations: Security warnings about wildcard patterns are preserved and documented
  • Filter bypass not possible: Filters are applied consistently in deliverToSubscriber() and deliverToWildcardSubscribers()

Style Notes

  • Consistent with codebase conventions: Follows existing Go style and aether patterns
  • Naming is clear: filteredSubscription, SubscriptionFilter, MatchActorPattern are all self-explanatory
  • Code organization: Pattern matching logic appropriately lives in pattern.go

Test Coverage

  • Excellent test coverage: 406 new lines of tests covering all filtering scenarios:
    • Event type filtering (single and multiple types)
    • Actor pattern filtering (exact, prefix wildcard, >)
    • Combined filters with AND logic
    • Nil and empty filter edge cases
    • Wildcard namespace + filter combinations
    • Multiple subscribers with different filters
    • Filtered and unfiltered subscriptions coexisting
    • Unsubscribe of filtered subscriptions
  • NATSEventBus integration: deliverToWildcardSubscribers() correctly applies filters before delivery
  • Pattern matching tests: Comprehensive tests for MatchActorPattern covering dots, wildcards, and edge cases

Architecture Alignment

  • Follows event sourcing principles: Filtering is non-destructive - events remain in the event stream
  • Namespace isolation preserved: Filters work within namespace boundaries, complementing wildcard patterns
  • Client-side filtering: Appropriate design choice documented in comments (server-side for namespaces via NATS, client-side for types/actors)
  • Metrics integration: Existing metrics correctly track filtered subscriptions

Verdict

LGTM

This is a well-designed, thoroughly tested implementation that addresses all acceptance criteria from Issue #21. The code integrates seamlessly with existing wildcard support and metrics, maintains backward compatibility, and includes excellent documentation and test coverage. Ready to merge.

🤖 Generated with Claude Code

## AI Code Review > This is an automated review generated by the code-reviewer agent. ### Summary This PR successfully implements namespace event filtering via SubscribeWithFilter, enabling efficient event handling by filtering on event types and actor patterns. The implementation integrates cleanly with existing wildcard subscription support and metrics infrastructure. Code quality is excellent with comprehensive test coverage. ### Findings #### Code Quality - **Excellent refactoring**: The conversion from []chan *Event to []*filteredSubscription is cleanly executed throughout EventBus - **Good abstraction**: SubscriptionFilter encapsulates filtering logic with clear IsEmpty() and Matches() methods - **Consistent pattern**: MatchActorPattern follows the same wildcard semantics as MatchNamespacePattern (*, >) - **Clean integration**: Subscribe() delegates to SubscribeWithFilter(pattern, nil), reducing code duplication - **Well-documented**: Comprehensive godoc comments with examples for SubscribeWithFilter and SubscriptionFilter - **Non-breaking change**: Backward compatibility maintained - existing Subscribe() calls continue to work #### Potential Bugs - **No issues found**: The AND logic for combined filters is correctly implemented - **Nil handling**: Filter nil checks are appropriate (nil or IsEmpty() means no filtering) - **Edge cases covered**: Empty patterns, nil events, and empty filters are all handled correctly in tests #### Security Concerns - **No security concerns identified**: Filtering happens client-side as documented, which is appropriate - **Wildcard considerations**: Security warnings about wildcard patterns are preserved and documented - **Filter bypass not possible**: Filters are applied consistently in deliverToSubscriber() and deliverToWildcardSubscribers() #### Style Notes - **Consistent with codebase conventions**: Follows existing Go style and aether patterns - **Naming is clear**: filteredSubscription, SubscriptionFilter, MatchActorPattern are all self-explanatory - **Code organization**: Pattern matching logic appropriately lives in pattern.go #### Test Coverage - **Excellent test coverage**: 406 new lines of tests covering all filtering scenarios: - Event type filtering (single and multiple types) - Actor pattern filtering (exact, prefix wildcard, >) - Combined filters with AND logic - Nil and empty filter edge cases - Wildcard namespace + filter combinations - Multiple subscribers with different filters - Filtered and unfiltered subscriptions coexisting - Unsubscribe of filtered subscriptions - **NATSEventBus integration**: deliverToWildcardSubscribers() correctly applies filters before delivery - **Pattern matching tests**: Comprehensive tests for MatchActorPattern covering dots, wildcards, and edge cases ### Architecture Alignment - **Follows event sourcing principles**: Filtering is non-destructive - events remain in the event stream - **Namespace isolation preserved**: Filters work within namespace boundaries, complementing wildcard patterns - **Client-side filtering**: Appropriate design choice documented in comments (server-side for namespaces via NATS, client-side for types/actors) - **Metrics integration**: Existing metrics correctly track filtered subscriptions ### Verdict **LGTM** This is a well-designed, thoroughly tested implementation that addresses all acceptance criteria from Issue #21. The code integrates seamlessly with existing wildcard support and metrics, maintains backward compatibility, and includes excellent documentation and test coverage. Ready to merge. 🤖 Generated with Claude Code
HugoNijhuis merged commit ef73fb6bfd into main 2026-01-10 22:51:21 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: flowmade-one/aether#54