Repository navigation
perf(broadcast): skip a node's own Pub/Sub messages before decoding them - #349
Merged
Merged
Conversation
cosmin-staicu
requested review from
alinahornet,
cosminvlad,
florin-munteanu-uipath,
litheon,
lucianaparaschivei and
razvalex
as code owners
November 2, 2026 05:05
|
🔎 Maintainer heads-up: automated triage flagged this PR as potentially material, so it may need a signed CLA in addition to the DCO sign-off. Strong signals
This is advisory only — the bot does not decide. Please judge against the CLA criteria (material, product-critical, patent-sensitive, corporate contributor, broad commercial use). Note that thresholds can be gamed by splitting PRs, so use your judgement.
|
cosmin-staicu
force-pushed
the
feat/skip-own-events
branch
from
November 2, 2026 09:39
4800c73 to
a1111ad
Compare
cosmin-staicu
force-pushed
the
feat/pubsub-skip-own
branch
from
November 2, 2026 09:39
607ef0e to
a10ef3c
Compare
cosmin-staicu
force-pushed
the
feat/skip-own-events
branch
from
November 2, 2026 11:17
a1111ad to
7ad4075
Compare
cosmin-staicu
force-pushed
the
feat/pubsub-skip-own
branch
from
November 2, 2026 11:17
a10ef3c to
61a65ac
Compare
cosmin-staicu
force-pushed
the
feat/skip-own-events
branch
from
November 2, 2026 11:40
7ad4075 to
bdabaa2
Compare
cosmin-staicu
force-pushed
the
feat/pubsub-skip-own
branch
from
November 2, 2026 11:40
61a65ac to
f9e941f
Compare
cosmin-staicu
force-pushed
the
feat/skip-own-events
branch
from
November 2, 2026 11:59
bdabaa2 to
ed4aee7
Compare
cosmin-staicu
force-pushed
the
feat/pubsub-skip-own
branch
from
November 2, 2026 11:59
f9e941f to
e684cd3
Compare
cosmin-staicu
force-pushed
the
feat/skip-own-events
branch
from
November 2, 2026 12:37
ed4aee7 to
6a137fd
Compare
cosmin-staicu
force-pushed
the
feat/pubsub-skip-own
branch
from
November 2, 2026 12:37
e684cd3 to
2e473ce
Compare
cosmin-staicu
force-pushed
the
feat/skip-own-events
branch
from
November 2, 2026 14:58
6a137fd to
bcbc5b5
Compare
cosmin-staicu
force-pushed
the
feat/pubsub-skip-own
branch
from
November 2, 2026 14:58
2e473ce to
33be513
Compare
cosmin-staicu
force-pushed
the
feat/skip-own-events
branch
from
November 2, 2026 15:39
bcbc5b5 to
6638c9a
Compare
cosmin-staicu
force-pushed
the
feat/pubsub-skip-own
branch
from
November 2, 2026 15:39
33be513 to
4fd2e9b
Compare
cosmin-staicu
force-pushed
the
feat/skip-own-events
branch
from
November 2, 2026 15:46
6638c9a to
96714f8
Compare
cosmin-staicu
force-pushed
the
feat/pubsub-skip-own
branch
from
November 2, 2026 15:46
4fd2e9b to
8398c7b
Compare
cosmin-staicu
force-pushed
the
feat/skip-own-events
branch
from
November 2, 2026 16:02
96714f8 to
b333496
Compare
cosmin-staicu
force-pushed
the
feat/pubsub-skip-own
branch
2 times, most recently
from
November 2, 2026 16:29
9bb74cd to
8566125
Compare
cosmin-staicu
force-pushed
the
feat/skip-own-events
branch
from
November 2, 2026 16:29
b333496 to
3d3cf27
Compare
cosmin-staicu
force-pushed
the
feat/pubsub-skip-own
branch
from
November 2, 2026 16:53
8566125 to
5d4f78a
Compare
cosmin-staicu
force-pushed
the
feat/skip-own-events
branch
from
November 2, 2026 16:53
3d3cf27 to
5ac6cae
Compare
cosmin-staicu
force-pushed
the
feat/skip-own-events
branch
from
November 3, 2026 09:34
6b3e9d7 to
83c0fb2
Compare
cosmin-staicu
force-pushed
the
feat/pubsub-skip-own
branch
2 times, most recently
from
November 3, 2026 09:55
09ead8f to
fe736a6
Compare
cosmin-staicu
force-pushed
the
feat/skip-own-events
branch
2 times, most recently
from
November 3, 2026 10:13
292dd31 to
978f2a8
Compare
cosmin-staicu
force-pushed
the
feat/pubsub-skip-own
branch
from
November 3, 2026 10:13
fe736a6 to
37662db
Compare
cosmin-staicu
force-pushed
the
feat/skip-own-events
branch
from
November 3, 2026 10:56
978f2a8 to
f1a29d6
Compare
cosmin-staicu
force-pushed
the
feat/pubsub-skip-own
branch
from
November 3, 2026 10:56
37662db to
9e36537
Compare
cosmin-staicu
force-pushed
the
feat/skip-own-events
branch
from
November 3, 2026 11:24
f1a29d6 to
baff21c
Compare
cosmin-staicu
force-pushed
the
feat/pubsub-skip-own
branch
from
November 3, 2026 11:24
9e36537 to
9b11900
Compare
cosmin-staicu
force-pushed
the
feat/skip-own-events
branch
from
November 3, 2026 12:34
baff21c to
8f9ab38
Compare
cosmin-staicu
force-pushed
the
feat/pubsub-skip-own
branch
from
November 3, 2026 12:34
9b11900 to
4f47a43
Compare
cosmin-staicu
force-pushed
the
feat/skip-own-events
branch
from
November 3, 2026 13:06
8f9ab38 to
4646ae4
Compare
cosmin-staicu
force-pushed
the
feat/pubsub-skip-own
branch
2 times, most recently
from
November 3, 2026 13:33
57fe475 to
b2330cf
Compare
cosmin-staicu
force-pushed
the
feat/skip-own-events
branch
2 times, most recently
from
November 3, 2026 13:53
8f93501 to
f003b9b
Compare
cosmin-staicu
force-pushed
the
feat/pubsub-skip-own
branch
from
November 3, 2026 13:53
b2330cf to
ab0ee33
Compare
cosmin-staicu
force-pushed
the
feat/skip-own-events
branch
from
November 3, 2026 15:44
f003b9b to
3aa016e
Compare
cosmin-staicu
force-pushed
the
feat/pubsub-skip-own
branch
from
November 3, 2026 15:44
ab0ee33 to
c2bc17a
Compare
A Pub/Sub subscriber also receives what its own node publishes. Each such message went through a full System.Text.Json decode, about 1.75 KB, and was then dropped by SameSource. A Pub/Sub message is a single value, so unlike the stream entries it cannot carry the source beside the payload. Formatters get an optional public capability, IEventSourceMatcherProvider, which builds an IEventSourceMatcher for one source. The matcher reads the payload with Utf8JsonReader, finds the top-level source property wherever it is, and compares its unescaped text with the node's source, allocating nothing. The subscriber builds the matcher once and drops a matching message without decoding it. The wire format is unchanged. The matcher only reports a message as own when the decode would drop it: - It compares against the source as this node writes it (OriginalString) and its normalized form. Each text is kept only when the formatter's own decode of a probe payload that carries it gives an event SameSource counts as this node's. - A case-only difference, a missing, null or nested source, a second source property (the last one wins the decode), trailing content and malformed JSON are not matched. Those messages are decoded and compared as before. - While the subscriber's debug or trace log is on, every message is decoded, so the own-message logs keep the event id. CacheEventFormatter matches "Source". The CloudEvents formatter matches the structured-mode "source" attribute when it wraps a JsonEventFormatter; it writes the same structured JSON, and its fast decode still allocates the id, the data and the wrapper per own message. The matcher source is linked into UiPath.Caching.CloudEvents. A custom formatter without the capability keeps decode-then-compare. The Streams reader is unchanged. A stream entry without the src field comes from a 3.0 writer, so it is another node's except for a node's own pre-upgrade backlog. An allocation probe over 1000 own messages goes from 1751 bytes per message (decoded) to 0. Signed-off-by: Cosmin Staicu <cosmin.staicu@uipath.com>
cosmin-staicu
force-pushed
the
feat/pubsub-skip-own
branch
from
November 3, 2026 15:57
c2bc17a to
430e09e
Compare
|
alinahornet
approved these changes
Nov 3, 2026
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.



Summary
On the Redis Pub/Sub transport a node also receives the messages it publishes, and decoded each one in full (System.Text.Json) before dropping its own. Formatters can now read only the event source from the payload, so a node's own message is dropped without a decode. The message format does not change.
OnMessage(payload) + formatter has a source matcher and it says "from this node" -> drop, no decode decode -> SameSource? drop : apply // unchanged otherwiseIEventSourceMatcherProvider.CreateSourceMatcher(Uri)builds a matcher once per subscriber;IEventSourceMatcher.IsFromSource(ReadOnlyMemory<byte>)checks one payload.CacheEventFormatterimplements it (Source); the CloudEvents formatter implements it when it wraps a JSON formatter (source). Both use oneUtf8JsonReader-based matcher that compares withValueTextEquals(JSON escapes handled) and allocates nothing.SameSource. Custom formatters without the capability keep decode-then-compare.GetOrAddResultRedisIntegrationTests.A_redis_hit_allocates_about_what_get_or_add_doesmoves to a new non-parallelRedisAllocationcollection with the same Redis fixture, so its allocation count no longer includes other tests running in parallel.Evidence
1000 own messages: 1751 -> 0 bytes per own message.
37 new cases: own skipped with 0 decodes, foreign applied, escaped, non-ASCII and case-only sources, Source after Data or missing, custom formatter, CloudEvents, allocation probe. net10.0 4364 passed, net8.0 4322 passed; the moved test passed 6/6 full runs.
Merge Danger
Door: two-way; the wire format is unchanged.
Blast Radius: Pub/Sub readers. An own message that is itself malformed no longer logs the "Event invalid" warning when Debug and Trace are off. The CloudEvents formatter test-decodes a sample payload once per subscriber when the topic is created.