|
2 | 2 |
|
3 | 3 | === Advanced Topics
|
4 | 4 |
|
| 5 | +==== Filtering |
| 6 | + |
| 7 | +RabbitMQ Stream provides a server-side filtering feature that avoids reading all the messages of a stream and filtering only on the client side. |
| 8 | +This helps to save network bandwidth when a consuming application needs only a subset of messages, e.g. the messages from a given geographical region. |
| 9 | + |
| 10 | +The filtering feature works as follows: |
| 11 | + |
| 12 | +* each message is published with an associated _filter value_ |
| 13 | +* a consumer that wants to enable filtering must: |
| 14 | +** define one or several filter values |
| 15 | +** define some client-side filtering logic |
| 16 | + |
| 17 | +Why does the consumer need to define some client-side filtering logic? |
| 18 | +Because the server-side filtering is probabilistic: messages that do not match the filter value(s) can still be sent to the consumer. |
| 19 | +The server uses a https://en.wikipedia.org/wiki/Bloom_filter[bloom filter], _a space-efficient probabilistic data structure_, where false positives are possible. |
| 20 | +Despite this, the filtering saves some bandwidth, which is its primary goal. |
| 21 | + |
| 22 | +===== Filtering on the Publishing Side |
| 23 | + |
| 24 | +Filtering on the publishing side consists in defining some logic to extract the filter value from a message. |
| 25 | +The following snippet shows how to extract the filter value from an application property: |
| 26 | + |
| 27 | +.Declaring a producer with logic to extract a filter value from each message |
| 28 | +[source,java,indent=0] |
| 29 | +-------- |
| 30 | +include::{test-examples}/FilteringUsage.java[tag=producer-simple] |
| 31 | +-------- |
| 32 | +<1> Get filter value from `state` application property |
| 33 | + |
| 34 | +Note the filter value can be null: the message is then published in a regular way. |
| 35 | +It is called in this context an _unfiltered_ message. |
| 36 | + |
| 37 | +===== Filtering on the Consuming Side |
| 38 | + |
| 39 | +A consumer needs to set up one or several filter values and some filtering logic to enable filtering. |
| 40 | +The filtering logic must be consistent with the filter values. |
| 41 | +In the next snippet, the consumer wants to process only messages from the state of California. |
| 42 | +It sets a filter value to `california` and a predicate that accepts a message only if the `state` application properties is `california`: |
| 43 | + |
| 44 | +.Declaring a consumer with a filter value and filtering logic |
| 45 | +[source,java,indent=0] |
| 46 | +-------- |
| 47 | +include::{test-examples}/FilteringUsage.java[tag=consumer-simple] |
| 48 | +-------- |
| 49 | +<1> Set filter value |
| 50 | +<2> Set filtering logic |
| 51 | + |
| 52 | +The filter logic is a `Predicate<Message>`. |
| 53 | +It must return `true` if a message is accepted, following the same semantics as `java.util.stream.Stream#filter(Predicate)`. |
| 54 | + |
| 55 | +As stated above, not all messages must have an associated filter value. |
| 56 | +Many applications may not need some filtering, so they can publish messages the regular way. |
| 57 | +And a stream can contain messages with and without an associated filter value. |
| 58 | + |
| 59 | +By default, messages without a filter value (a.k.a _unfiltered_ messages) are not sent to a consumer that enabled filtering. |
| 60 | + |
| 61 | +But what if a consumer wants to process messages with a filter value and messages without any filter value as well? |
| 62 | +It must use the `matchUnfiltered()` method in its declaration and also make sure to keep the filtering logic consistent: |
| 63 | + |
| 64 | +.Declaring a consumer with a filter value and filtering logic |
| 65 | +[source,java,indent=0] |
| 66 | +-------- |
| 67 | +include::{test-examples}/FilteringUsage.java[tag=consumer-match-unfiltered] |
| 68 | +-------- |
| 69 | +<1> Request messages from California |
| 70 | +<2> Request messages without a filter value as well |
| 71 | +<3> Let both types of messages pass |
| 72 | + |
| 73 | +In the example above, the filtering logic has been adapted to let pass `california` messages _and_ messages without a state set as well. |
| 74 | + |
5 | 75 | ==== Using Native `epoll`
|
6 | 76 |
|
7 | 77 | The stream Java client uses the https://netty.io/[Netty] network framework and its Java NIO transport implementation by default.
|
|
0 commit comments