Summary
Second-pass performance/code-quality audit finding. SubscriptionFilter stores list-valued filters as Vecs, and the runtime checks those vectors linearly for every envelope received by every filtered subscription.
Evidence
crates/arcp-runtime/src/runtime/subscription.rs:154 defines matches(filter, envelope).
crates/arcp-runtime/src/runtime/subscription.rs:155 through crates/arcp-runtime/src/runtime/subscription.rs:160 checks session_id with Vec::contains.
crates/arcp-runtime/src/runtime/subscription.rs:163 through crates/arcp-runtime/src/runtime/subscription.rs:168 checks trace_id with Vec::contains.
crates/arcp-runtime/src/runtime/subscription.rs:171 through crates/arcp-runtime/src/runtime/subscription.rs:184 repeats the same pattern for job and stream ids.
crates/arcp-runtime/src/runtime/subscription.rs:187 through crates/arcp-runtime/src/runtime/subscription.rs:190 linearly scans type filters.
Why it matters
This code is on the live fan-out path. Cost scales with subscriptions * envelopes * filter-list-size, and the same filter vectors are rescanned for every envelope even though they are immutable after subscription registration.
Proposed fix
Compile SubscriptionFilter into a runtime filter representation at registration time, using HashSet/BTreeSet for fields where membership is the hot operation and preserving the wire Vec only at API boundaries.
Acceptance criteria
FilteredReceiver stores a compiled filter with O(1) or O(log n) membership checks for id/type lists.
- The public wire/API shape of
SubscriptionFilter remains unchanged.
- A benchmark or regression test covers a subscription with large filter lists receiving many envelopes.
Summary
Second-pass performance/code-quality audit finding.
SubscriptionFilterstores list-valued filters asVecs, and the runtime checks those vectors linearly for every envelope received by every filtered subscription.Evidence
crates/arcp-runtime/src/runtime/subscription.rs:154definesmatches(filter, envelope).crates/arcp-runtime/src/runtime/subscription.rs:155throughcrates/arcp-runtime/src/runtime/subscription.rs:160checkssession_idwithVec::contains.crates/arcp-runtime/src/runtime/subscription.rs:163throughcrates/arcp-runtime/src/runtime/subscription.rs:168checkstrace_idwithVec::contains.crates/arcp-runtime/src/runtime/subscription.rs:171throughcrates/arcp-runtime/src/runtime/subscription.rs:184repeats the same pattern for job and stream ids.crates/arcp-runtime/src/runtime/subscription.rs:187throughcrates/arcp-runtime/src/runtime/subscription.rs:190linearly scans type filters.Why it matters
This code is on the live fan-out path. Cost scales with
subscriptions * envelopes * filter-list-size, and the same filter vectors are rescanned for every envelope even though they are immutable after subscription registration.Proposed fix
Compile
SubscriptionFilterinto a runtime filter representation at registration time, usingHashSet/BTreeSetfor fields where membership is the hot operation and preserving the wireVeconly at API boundaries.Acceptance criteria
FilteredReceiverstores a compiled filter with O(1) or O(log n) membership checks for id/type lists.SubscriptionFilterremains unchanged.