-
-
Notifications
You must be signed in to change notification settings - Fork 107
Filter publications by tags on server-side by providing tags filter in subscription request #511
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #511 +/- ##
==========================================
+ Coverage 83.45% 83.82% +0.36%
==========================================
Files 39 42 +3
Lines 9123 9544 +421
==========================================
+ Hits 7614 8000 +386
- Misses 1150 1166 +16
- Partials 359 378 +19 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Hi, just to clarify — our PR was accidentally closed because the forked repo got mistakenly deleted by a teammate. We originally explored CEL for its flexibility and expressive power, but as you mentioned, it introduces high allocation and GC pressure in the broadcast hot path. Your tag-based filtering approach is a much better fit for Centrifuge’s design goals: zero allocations, simple and efficient structure, native Protobuf/JSON compatibility. While it’s less general than CEL, it covers the core subscription filtering needs while keeping performance predictable. Thanks a lot for implementing this and aligning it so well with the project’s priorities! |
|
@torbensen awesome, thx for letting me know! Aiming to release filtering by tags soon, need to prepare various parts for it - docs, blog post, SDK changes. It will be part of Javascript SDK only on start. If you find out sth related to it – please let me know. |
This allows clients to subscribe to a channel while providing publication tags filter, so that only relevant publications with tags that satisfy the provided filter are delivered. This may optimize bandwidth and reduce processing overhead on the client side.
Design goals
To align with Centrifuge’s goals, the publication filter implementation should follow these principles:
Implementation
The initial idea was to use CEL expressions for the filtering. See #502 for the community PR with CEL support. But during the evaluation of the idea observed a huge allocation penalty which may come with CEL expression evaluations during publication broadcasts to many subscribers - allocs happen in the hot path where we don't want to have allocations at all (see below the benchmark). Thus more CPU usage, more load on GC. And unfortunately the real overhead is not very predictable and can be performance killer. Another concern – CEL expressions are hard to make programatically – no API for that on the client side. So while we successfully using CEL in other places in Centrifugo – here it seems not a good fit.
So the decision was to proceed with a custom implementation, it's of course limited compared to CEL and other expression engines – but it fully follows the principles outlined above.
Every Publication may contain
tagswhich ismap[string]stringin Protobuf schema. The mechanism introduced here allows filtering publications based on attached tags.The filtering system is based on
NodeFiltermessage type from the Protobuf schema (note, we are not using enums for JSON interop reasons) which may be passed in subscription request:An optional
tf(tags filter) field withNodeFiltermay be set inSubscribeRequest. Since filtering relies to the client protocol type – the filtering is not pluggable, but part of the core.Let's compare to CEL. Example, the overhead of broadcasting to 10k subscribers:
Or, memory overhead for creating the same filter:
Tags filtering additionally supports:
Filters are validated at subscription time. Common validation errors include:
If a filter is invalid, the server returns
ErrorBadRequesterror to the client, and the subscription is rejected.During filter evaluation (publication broadcast):
Example
Example of possible filter usage in
centrifuge-js:Or sth more complex:
It's rather simple to provide a type-safe (and typo-safe) helper for filter construction on the real-time SDK side, but not doing it for now. I.e. sth like this may be done (can live outside of SDK actually), sth like this: