Skip to content

feat(core) #197: carry the caller's MDC into the threads that run your function - #205

Open
astubbs wants to merge 6 commits into
masterfrom
feat/mdc-context-propagation
Open

feat(core) #197: carry the caller's MDC into the threads that run your function#205
astubbs wants to merge 6 commits into
masterfrom
feat/mdc-context-propagation

Conversation

@astubbs

@astubbs astubbs commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Description

Raised as a non-blocking finding on #197 by a user in the confluentinc#907 thread (mirrored on this fork as #195): the
caller's SLF4J MDC is not propagated into the worker pool.

Confirmed on master before writing anything:

  • PC sets exactly two MDC keys of its own - pcId (MDC_INSTANCE_ID, put in addInstanceMDC() and in
    BrokerPollSystem) and offset (MDC_WORK_CONTAINER_DESCRIPTOR).
  • MDC.getCopyOfContextMap() and MDC.setContextMap() appear nowhere in the repository.

So a caller who has established diagnostic context - a trace_id, a request_id, a tenant - loses all of it the
moment a record crosses into the worker pool, and again crossing into vert.x, Reactor or Mutiny. The logs their
function writes cannot be correlated back to the originating request.

Where the capture and the restore live

New MdcPropagation (core internal): capture() on the thread that has the context, and enter(..) returning
an AutoCloseable scope on the thread that runs the work.

Boundary Capture Restore
Worker pool submitWorkToPoolInner, on the controller thread at submit time try-with-resources around the submitted task
vert.x event loop addVertxHooks and the web-request callback, on the worker thread around each handler PC attaches to the vert.x Future
Reactor scheduler react(..)'s wrapper, on the worker thread around Mono.fromCallable and both terminal signals
Mutiny executor onRecord(..)'s wrapper, on the worker thread around Uni.deferred and both terminal signals

The caller's own snapshot is taken in supervisorLoop - i.e. on the thread that calls poll*(). That is the only
moment it is reachable: none of PC's threads exist yet and the SLF4J MDC is not inheritable. The controller and
broker-poller threads then adopt(..) it outright (they serve one PC instance for life, so there is no later task
to leak into), which is also what makes the submit-time capture pick up the caller's context.

Judgement calls

Precedence - PC's keys win. pcId and offset are applied after the caller's map at every call site, so a
caller key of the same name cannot shadow them. PC's own log lines are read by those keys; a caller key shadowing
offset would silently corrupt PC's own diagnostics. Covered by a test that deliberately collides on pcId.

On by default, with ParallelConsumerOptions.propagateMdc as the kill switch, wired through
PCModule.mdcPropagation(). Not propagating fails silently, for everyone, and only ever gets fixed by users who
read a changelog; propagating fails visibly, as one extra key in a log line, and can be switched off. The
asymmetry decides it. Setting it false restores the old behaviour exactly - leak included - so it is a true
revert rather than half of one.

The one genuine risk of a default-on capture is that it is taken once, at poll*(): a request-scoped value in the
MDC at that moment gets pinned to the consumer for its whole life, which is the same "actively misleading logs"
failure this PR exists to prevent. Mitigated rather than ignored - PC logs the captured keys (never the values,
which are the user's data) at INFO on startup, so the mistake is discoverable. It is also called out on the option's
javadoc.

That INFO line is once per consumer instance, not per poll and not per record, and structurally so:
captureCallersDiagnosticContext() is called only from supervisorLoop, which throws IllegalStateException if
poll*() is called more than once. There is no hot path it can reach.

The leak is fixed too, not just the propagation. On master, whatever the user function puts into the MDC stays
on the pooled thread for the next, unrelated, record. The restore scope fixes that as a side effect, and it is the
half of this change that matters most.

Null-safety. getCopyOfContextMap() returns null for an empty context; that is the normal path and is
handled throughout, with a test asserting no NPE and correct behaviour when the caller sets nothing at all.

Hot-path cost: measured, not assumed. getCopyOfContextMap() returns null without allocating when the
context is empty, enter(null) returns a shared singleton scope, and pcId is only ever set when setMyId() has
been used. Rather than leave that as reasoning, it was measured with ThreadMXBean.getThreadAllocatedBytes over a
million capture()/enter()/close() cycles on logback 1.6.1:

Case Bytes allocated per batch
Caller never touches the MDC (the default) 0
Propagation disabled 0
2-key MDC - capture() on the controller thread 240
2-key MDC - enter()+close() on a clean worker thread 184

So the "nil for users who never touch the MDC" claim holds exactly - zero bytes, not merely "small". For a user who
has set MDC it is ~424 bytes per batch, against the groupingBy collector, two ArrayLists, a
PollContextInternal and a FutureTask that runUserFunction already allocates per batch.

One caveat now recorded in the inflight note: the zero is a property of logback's MDCAdapter, which returns
null for an empty context. Some other SLF4J bindings return an empty map instead, which would make capture()
allocate one small map per batch. Behaviour is correct either way; only the zero-allocation figure is
binding-specific.

Modules covered, and what is not

Covered: core (worker pool), vertx (event loop), reactor (scheduler), and mutiny. Mutiny was not in
the brief, but it is a genuine third boundary of exactly the same shape as Reactor's - runSubscriptionOn(executor)
means the user's function does not run on the worker thread either - so leaving it out would have shipped a
documented inconsistency for ~5 lines of saving. It has its own test like the others.

Deliberately not covered: the operator chains of the Publisher/Uni the user returns. We carry the context
into the invocation of their function and into PC's terminal signal handling; following it further, onto whatever
schedulers their own chain hops to, needs Reactor's io.micrometer:context-propagation and is the user's call, not
ours. Recorded in the inflight note so the next person does not treat it as an oversight.

Tests

17 tests: MdcPropagationTest (9, the primitive itself), MdcContextPropagationTest (5, end-to-end through
the real worker pool), and 1 each in vertx / reactor / mutiny. They assert the caller's key is visible inside the
user function, that PC's own keys survive and win a collision, that the context does not leak to a later task on the
same pooled thread, and that an empty/null context does not NPE.

The three engine tests share MdcBoundaryProbe (core test-jar, the same route TestConventionRules and
WireMockUtils already take) by composition - each already extends its own module's unit-test base, so a common
superclass is not available. The probe holds only what is genuinely identical: the caller key/value, the observation
bookkeeping, the MDC teardown, and the "context was visible" assertion. The per-engine assertions stay in the tests,
because they are what stops a test quietly degrading into a re-run of the core worker-pool case, and they really do
differ - Reactor asserts its scheduler thread positively (boundedElastic), while vertx and Mutiny can only
assert "not a pc- thread" since their executor is caller-supplied.

Every one of them is verified to be able to fail. A green test that cannot go red proves nothing, so:

  • The leak test was re-run with propagation disabled: it fails with
    expected to be empty but was: [poison_from_offset_2, poison_from_offset_3, poison_from_offset_0, poison_from_offset_1]
    • four keys carried across five records on one pooled thread. That is the real pre-existing defect on master.
  • The leak test asserts threadsUsed has size 1, so it cannot pass by accidentally getting a fresh thread per
    record. maxConcurrency(1) makes the reuse deterministic rather than lucky.
  • The three engine tests were each re-run with propagateMdc(false) (temporarily overriding
    initAsyncConsumer(..)) and each failed on its own "context must be visible on the <engine>" assertion,
    reporting values seen: [null, ...]. Re-verified again after the shared-probe refactor, so the extraction did not
    quietly defuse them. They also assert which thread observed - Reactor positively (boundedElastic), vertx and
    Mutiny as "not a pc- thread" - so they cannot silently stop covering the second boundary.

No existing assertion was weakened. The one failure I hit while developing (ReactorMdcPropagationTest expecting 4
records) was my own arithmetic - ReactorPCTest primes a 4th record in its own @BeforeEach, ReactorUnitTestBase
primes none - diagnosed from the surefire report (exactly 3 processed, 3 primed) rather than papered over with a
longer timeout.

Full unit suite (bin/ci-unit-test.sh) green across all 11 modules; bin/check-copyright-headers.sh clean;
upstream-map.py validate OK.

Refs #197, #195, confluentinc#907.

Merged up from master

Master moved a long way while this was open (the upstream-issue mirror, the repo-hygiene workflow, four SIGPIPE fixes). Merged in at d4fed639; one conflict, in upstream-map.yaml.

The conflict. #114 restructured that file: it now tracks upstream PRs only, because every upstream issue has a fork mirror, and it deleted ten tracking-only entries - one of which sat immediately beside the entry this PR adds. Took master's deletions wholesale, then refitted this PR's entry to the new shape: block style, fork_issue: 195 cross-linking the mirror of confluentinc#907, and renamed issue-907-mdc-propagation -> mdc-context-propagation, since an issue- prefix now reads as one of the entries that commit removed. Safe to rename - nothing outside this branch referenced it. upstream-map.py validate: OK, 15 entries.

AGENTS.md is in slight tension on whether this entry should exist at all: the manifest "tracks upstream PRs only" and this maps to an issue, but it also says to record status: pr-open for your own fork work at each lifecycle transition. fork_issue: 195 satisfies both readings - the upstream issue's diagnosis and closing live on the mirror, this PR's lifecycle lives in the manifest. Happy to drop the entry instead if you read it the other way.

The new reference gate caught three real ones. #114 also added .github/scripts/issue-ref-gate.js, run by the PR Checklist check: below #1000 a reference must name its repo, because the fork's numbers sit entirely inside upstream's range. Ran the gate's own suspectRefs() over this PR's diff - three unqualified refs on added lines (two in the inflight note, one in MdcContextPropagationTest's javadoc), now zero. Also switched upstream #907 to confluentinc#907: the bare form still passes, but AGENTS.md asks new writing to name the owner rather than the role.

A latent race in this PR's own test probe, found by reading 16ac63b1. That commit fixed MultiInstanceMetricsTest for awaiting a counter that leads the value asserted, and generalised the rule. MdcBoundaryProbe had the same shape: it appended to threadsUsed and then to contextSeen, and the engine tests awaited contextSeen before asserting over threadsUsed - always one step ahead. It could not lose today, because each engine test primes exactly three records, but that is a property of the fixture rather than the probe. Now one Observation (thread + value) is added atomically to one collection, matching what MdcContextPropagationTest already did. Re-verified both Reactor and Mutiny still go RED under propagateMdc(false) afterwards.

This PR pushes AbstractParallelEoSStreamProcessor.java past 64 KiB - 65,185 -> 67,877 bytes, i.e. 2,341 past the pipe buffer. That matters because check-quarantine-owners.sh used to pipe that file into grep -q under pipefail, which inverts its answer once the file exceeds the buffer; it had 351 bytes of headroom. Master's cb8b1182 fixed it first, so nothing breaks - confirmed by running both forms against the real file: the old one reports NO-MATCH with rc=141, the new herestring reports MATCH. Worth knowing that this PR is what would have consumed that headroom, and that bin/check-shell-sigpipe.sh now guards the class repo-wide.

Checklist

  • Docs updated - option javadoc, MdcPropagation class javadoc, docs/inflight/branch-mdc-context-propagation.md, and an upstream-map.yaml entry refitted to the post-mirror schema. CHANGELOG.adoc deliberately untouched, per AGENTS.md (generated at release time, not a per-PR chore)
  • Tests added/updated - 17 new tests across 4 modules (9 + 5 in core, 1 each in vertx/reactor/mutiny), each verified to fail without the fix
  • Title & body reflect the final content of this PR
  • N/A - no CI runner or workflow files touched

🤖 Generated with Claude Code

https://claude.ai/code/session_01RtNUsxokE9g2pSEjBHZqNA

…r function

A caller who had established diagnostic context - a trace_id, a request_id, a
tenant - lost all of it the moment a record crossed into the worker pool, and
again crossing into vert.x, Reactor or Mutiny. The logs their user function
wrote could not be correlated back to the originating request. PC set only its
own two keys (pcId, offset) and called neither MDC.getCopyOfContextMap() nor
MDC.setContextMap() anywhere in the tree.

The context is snapshotted on the thread that calls poll*() - the only moment
it is reachable, since none of PC's threads exist yet and the SLF4J MDC is not
inheritable - and re-established around the user function on the thread that
actually runs it, then torn down again.

The teardown is the half that matters. Worker threads are pooled: one that
keeps the previous task's trace_id produces logs that are actively misleading,
which is worse than no context at all. That leak already existed on master for
the user function's own MDC.put calls - five records on one pooled thread carry
four poisoned keys - and is fixed by the same scope.

Precedence: PC's own pcId/offset are applied AFTER the caller's map at every
call site, so a caller key of the same name cannot shadow them. PC's own log
lines are read by those keys.

On by default, with ParallelConsumerOptions.propagateMdc as the kill switch.
Not propagating fails silently for everyone; propagating fails visibly, as one
extra key in a log line, and can be switched off. Setting it false restores the
old behaviour exactly, leak included, so it is a true revert rather than half
of one. PC logs the captured keys - never the values - at INFO, so that a
request-scoped value accidentally pinned for the life of the consumer is
discoverable rather than silently wrong.

Cost on the hot path is nil for anyone who never touches the MDC:
getCopyOfContextMap() returns null, allocating nothing, for an empty context,
and pcId is only ever set when setMyId() has been used.

Deliberately not covered: Reactor's and Mutiny's own operator chains. We carry
the context into the user's function and into PC's terminal signal handling;
following it through the Publisher/Uni they return needs Reactor's own
io.micrometer:context-propagation and is the user's call, not ours.

Upstream-Issue: confluentinc#907
Forwarded: not-needed
Applied-Upstream: no

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtNUsxokE9g2pSEjBHZqNA
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@claude

claude Bot commented Aug 5, 2026

Copy link
Copy Markdown

Claude is reviewing this PR

Todo list

  • Gather context (read CLAUDE.md, diff, changed files)
  • Understand the request (code review of MDC propagation PR)
  • Review core MdcPropagation primitive and its usage sites
  • Review engine integrations (vertx, reactor, mutiny)
  • Review tests for correctness and that they can actually fail
  • Post final review feedback

View job run

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

✅ Duplicate Code Report

Two engines run in parallel for cross-validation. Each has its own thresholds tuned to its baseline - the real safety net is the per-engine "max increase vs base" check.

✅ PMD CPD

PR Base Change
Clones 27 28 🙂 -1
Duplicated lines 822 850 ❤️ -28
Duplication 2.35% 2.43% 🙂 -0.08%
Rule Limit Status
Max duplication 5% ✅ Pass (2.35%)
Max increase vs base +0.1% ✅ Pass (-0.08%)

No new clones introduced by this PR.

✅ jscpd (language-agnostic)

PR Base Change
Clones 76 75 🫤 +1
Duplicated lines 1094 1087 :face_with_monocle: +7
Duplication 3.17% 3.24% 🙂 -0.07%
Rule Limit Status
Max duplication 5% ✅ Pass (3.17%)
Max increase vs base +0.1% ✅ Pass (-0.07%)
⚠️ 1 new clones introduced
  • 8 lines: parallel-consumer-mutiny/src/main/java/io/confluent/parallelconsumer/mutiny/MutinyProcessor.java:8 <-> parallel-consumer-reactor/src/main/java/io/confluent/parallelconsumer/reactor/ReactorProcessor.java:8

Powered by astubbs/duplicate-code-cross-check

…ntry

Lifecycle transition per AGENTS.md - the manifest is the source of truth for
the fork side, and nothing automated checks it, so an entry saying prs: [] with
an open PR rots silently.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtNUsxokE9g2pSEjBHZqNA
@claude

claude Bot commented Aug 5, 2026

Copy link
Copy Markdown

Claude finished @astubbs's task in 9m 8s —— View job


Claude's review of #205

Tasks

  • Gather context (PR body, changed files, comments)
  • Read AGENTS.md (this fork has no CLAUDE.md; AGENTS.md is the repo-instructions file)
  • Read the full diff (MdcPropagation, all 4 call sites, all new tests)
  • Compile core + vertx + reactor + mutiny modules
  • Run the new tests (MdcPropagationTest, MdcContextPropagationTest, VertxMdcPropagationTest, ReactorMdcPropagationTest, MutinyMdcPropagationTest) — all green
  • Verify the PR's central claim: flipped contextDoesNotLeakToTheNextTaskOnTheSamePooledThread() to propagateMdc(false) and re-ran it
  • Post findings

Summary

No issues found. This is a careful, well-scoped change and the PR body's claims check out under independent verification:

  • MdcPropagation (capture/enter/adopt) is a clean primitive: capture() returns null with no allocation on an empty context, enter(null) still establishes a CLEAR_ON_EXIT scope so a user function's own MDC.put doesn't leak, and enabled=false short-circuits both to true no-ops — a real, exact revert.
  • All four call sites (worker pool submit, vert.x onSuccess/onFailure/onComplete, Reactor Mono.fromCallable + both terminal signals, Mutiny Uni.deferred + both terminal signals) capture on the thread that has context and restore via try-with-resources on the thread that runs it — consistent with the table in the description.
  • Precedence is correct: PC's own MDC.put(MDC_INSTANCE_ID, ...) / MDC_WORK_CONTAINER_DESCRIPTOR calls all happen inside the enter(...) scope, so they apply on top of the caller's map, never before it.
  • Reproduced the pre-existing leak independently. Temporarily changed setupWithSingleWorkerThread(true)(false) in contextDoesNotLeakToTheNextTaskOnTheSamePooledThread() (then reverted) and got the exact failure the PR body quotes:
    expected to be empty but was: [poison_from_offset_2, poison_from_offset_3, poison_from_offset_0, poison_from_offset_1]
    — confirms the leak test is genuinely load-bearing, not a test that would pass either way.
  • bin/check-copyright-headers.sh is clean (238 files, 0 violations); copyright header/attribution changes on modified upstream files follow the fork's Confluent-notice + modifications-line convention correctly.
  • docs/inflight/branch-mdc-context-propagation.md and the upstream-map.yaml entry (issue-907-mdc-propagation) both follow the documented conventions (naming, status: pr-open, fork.prs: [205], distinct from the existing maintenance-signal entry for the same upstream issue).
  • Ran all engine tests individually (VertxMdcPropagationTest, ReactorMdcPropagationTest, MutinyMdcPropagationTest) — each passes and each asserts the observing thread is not a pc- worker thread, so they can't silently degrade into re-testing the core boundary.

One minor accuracy nit (non-blocking)

The PR checklist says "13 new tests across 4 modules." Actual count is 17: MdcPropagationTest has 9 @Test methods, MdcContextPropagationTest has 5 (not folded into the "9" as the prose might suggest), plus 1 each in the vertx/reactor/mutiny modules. Worth a quick edit to the checklist line so the number matches the diff, per this repo's own PR-discipline guidance on keeping stated counts accurate — not something that needs a new commit on its own.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

📌 Duplicate code detection tool report

The tool analyzed your source code and found the following degree of similarity between the files:

🆕 New file similarities introduced

File A File B Similarity (%)
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyMdcPropagationTest.java parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorMdcPropagationTest.java 48.0
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MdcBoundaryProbe.java parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MdcContextPropagationTest.java 41.2
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyMdcPropagationTest.java parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/VertxMdcPropagationTest.java 30.3
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 30.1
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java parallel-consumer-vertx/src/test-integration/java/io/confluent/parallelconsumer/vertx/integrationTests/VertxConcurrencyIT.java 30.0

🔺 Increased similarities

File A File B Base (%) PR (%) Change
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyBatchTest.java parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorBatchTest.java 79.0 80.8 +1.8
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyPCTest.java parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorPCTest.java 71.2 73.0 +1.8
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CoreBatchTest.java parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyBatchTest.java 50.7 51.6 +0.9
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CoreBatchTest.java parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorBatchTest.java 52.0 52.9 +0.9
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java 54.8 55.5 +0.7
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/TestConventionsArchTest.java 89.7 90.2 +0.6
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java 89.7 90.2 +0.6
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java 50.7 51.2 +0.5
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java 61.0 61.5 +0.5
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/TestConventionsArchTest.java parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java 90.5 91.0 +0.5
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java 36.8 37.2 +0.5
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java 33.9 34.4 +0.5
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyBatchTest.java parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/VertxBatchTest.java 49.1 49.6 +0.5
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 40.4 40.9 +0.5
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java 37.1 37.5 +0.5
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java 32.7 33.2 +0.5
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 32.4 32.9 +0.5
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/TestConventionsArchTest.java 90.3 90.8 +0.5
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorBatchTest.java parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/VertxBatchTest.java 50.3 50.8 +0.5
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/TestParallelEoSStreamProcessor.java 31.1 31.6 +0.5

...and 49 more

Full similarity report
parallel-consumer-core/src/main/java/io/confluent/csid/utils/Java8StreamUtils.java

📄 parallel-consumer-core/src/main/java/io/confluent/csid/utils/Java8StreamUtils.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/csid/utils/JavaUtils.java 35.59
parallel-consumer-core/src/test/java/io/confluent/csid/utils/CollectionUtils.java 33.48
parallel-consumer-core/src/main/java/io/confluent/csid/utils/JavaUtils.java

📄 parallel-consumer-core/src/main/java/io/confluent/csid/utils/JavaUtils.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/csid/utils/CollectionUtils.java 39.77
parallel-consumer-core/src/main/java/io/confluent/csid/utils/Java8StreamUtils.java 35.59
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 54.4 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 40.29
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PCRetriableException.java 36.97
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 36.79
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 35.21
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 34.91
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 34.91
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 33.93
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java 61.49 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java 55.49 ⚠️
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 40.88
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java 37.54
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java 33.16
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java 31.86
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java 61.49 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java 51.21 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java 37.25
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 32.91
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java 32.02
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java 30.53
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PCRetriableException.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PCRetriableException.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 36.97
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 33.37
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 54.4 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 52.97 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 44.64
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 34.74
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 33.32
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalRuntimeException.java 31.02
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 30.51
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 30.51
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerOptions.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerOptions.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/ProducerManager.java 32.03
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java 55.49 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java 51.21 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java 45.95
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java 34.43
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java 33.41
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/TestParallelEoSStreamProcessor.java 31.58
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 30.11
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java 45.95
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java 37.54
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java 37.25
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java 33.05
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContext.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContext.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/RecordContextInternal.java 35.8
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java 32.43
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java 34.43
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/RecordContextInternal.java 33.54
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java 33.16
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContext.java 32.43
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java 32.02
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/RecordContextInternal.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/RecordContextInternal.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContext.java 35.8
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java 33.54
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/BrokerPollSystem.java 33.67
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java 33.41
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/BrokerPollSystem.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/BrokerPollSystem.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java 33.67
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/ExternalEngine.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/ExternalEngine.java

File Similarity (%)
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelEoSStreamProcessor.java 39.58
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 60.37 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 52.97 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 50.68 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java 48.65
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 40.29
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalRuntimeException.java 39.8
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 36.99
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 33.4
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 33.4
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PCRetriableException.java 33.37
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalRuntimeException.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalRuntimeException.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 39.8
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 31.61
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 31.02
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/PCModule.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/PCModule.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/PCModuleTestEnv.java 31.83
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/ProducerManager.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/ProducerManager.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerOptions.java 32.03
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/ProducerManagerTest.java 30.44
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 51.46 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 37.25
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 37.25
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 36.99
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 35.21
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 34.74
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 32.57
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 60.37 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 51.46 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 48.13
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 46.87
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 46.87
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java 46.49
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 44.64
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 36.79
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalRuntimeException.java 31.61
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 48.65
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 46.49
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 45.11
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 37.8
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 37.8
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 50.68 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 48.13
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java 45.11
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 33.93
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 33.32
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 32.57
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 31.09
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 31.09
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 63.24 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 46.87
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java 37.8
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 37.25
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 34.91
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 33.4
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 31.09
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 30.51
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 63.24 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 46.87
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java 37.8
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 37.25
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 34.91
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 33.4
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 31.09
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 30.51
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/PartitionState.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/PartitionState.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/PartitionStateManager.java 30.41
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/PartitionStateManager.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/PartitionStateManager.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/WorkManager.java 39.82
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/PartitionState.java 30.41
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/ProcessingShard.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/ProcessingShard.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/ShardManager.java 36.56
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/ShardManager.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/ShardManager.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/ProcessingShard.java 36.56
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/WorkManager.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/WorkManager.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/PartitionStateManager.java 39.82
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/BrokerIntegrationTest.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/BrokerIntegrationTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/state/LatestResetTailNudgeIT.java 30.45
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/DrainingMemberRebalanceIT.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/DrainingMemberRebalanceIT.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/BrokerPollSystemDrainTest.java 30.96
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/KafkaSanityTests.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/KafkaSanityTests.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/csid/utils/LoopingResumingIteratorTest.java 33.93
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceHighVolumeTest.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceHighVolumeTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/VeryLargeMessageVolumeTest.java 55.48 ⚠️
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java 47.01
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceRebalanceTest.java 38.66
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceRebalanceTest.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceRebalanceTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/VeryLargeMessageVolumeTest.java 44.18
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java 41.17
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceHighVolumeTest.java 38.66
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/RebalanceEoSDeadlockTest.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/RebalanceEoSDeadlockTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/RebalanceTest.java 36.49
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/RebalanceTest.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/RebalanceTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/RebalanceEoSDeadlockTest.java 36.49
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/VeryLargeMessageVolumeTest.java 60.69 ⚠️
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceHighVolumeTest.java 47.01
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceRebalanceTest.java 41.17
parallel-consumer-vertx/src/test-integration/java/io/confluent/parallelconsumer/vertx/integrationTests/VertxConcurrencyIT.java 30.04
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/VeryLargeMessageVolumeTest.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/VeryLargeMessageVolumeTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java 60.69 ⚠️
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceHighVolumeTest.java 55.48 ⚠️
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceRebalanceTest.java 44.18
parallel-consumer-vertx/src/test-integration/java/io/confluent/parallelconsumer/vertx/integrationTests/VertxConcurrencyIT.java 39.31
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/chaostests/AbstractRevokeUnderWorkScenario.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/chaostests/AbstractRevokeUnderWorkScenario.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/chaostests/ChaosChurnStormIT.java 48.39
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkIT.java 35.48
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/chaostests/ChaosChurnStormIT.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/chaostests/ChaosChurnStormIT.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/chaostests/AbstractRevokeUnderWorkScenario.java 48.39
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/chaostests/ChaosScenarioBase.java 37.64
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkCooperativeIT.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkCooperativeIT.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkIT.java 48.69
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkIT.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkIT.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkCooperativeIT.java 48.69
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/chaostests/AbstractRevokeUnderWorkScenario.java 35.48
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/chaostests/ChaosScenarioBase.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/chaostests/ChaosScenarioBase.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/chaostests/ChaosChurnStormIT.java 37.64
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/state/LatestResetTailNudgeIT.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/state/LatestResetTailNudgeIT.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/BrokerIntegrationTest.java 30.45
parallel-consumer-core/src/test/java/io/confluent/csid/utils/CollectionUtils.java

📄 parallel-consumer-core/src/test/java/io/confluent/csid/utils/CollectionUtils.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/csid/utils/JavaUtils.java 39.77
parallel-consumer-core/src/main/java/io/confluent/csid/utils/Java8StreamUtils.java 33.48
parallel-consumer-core/src/test/java/io/confluent/csid/utils/LoopingResumingIteratorTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/csid/utils/LoopingResumingIteratorTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/KafkaSanityTests.java 33.93
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/BatchTestBase.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/BatchTestBase.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CoreBatchTest.java 30.79
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CheckQuarantineOwnersScriptTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CheckQuarantineOwnersScriptTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/QuarantineLaneReportScriptTest.java 45.07
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/QuarantineRegistryScriptTest.java 44.35
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CommitRejectionTestBase.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CommitRejectionTestBase.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTest.java 32.55
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerCommitTimeoutTest.java 32.48
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CoreBatchTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CoreBatchTest.java

File Similarity (%)
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorBatchTest.java 52.9 ⚠️
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyBatchTest.java 51.62 ⚠️
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/VertxBatchTest.java 45.15
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/BatchTestBase.java 30.79
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MdcBoundaryProbe.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MdcBoundaryProbe.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MdcContextPropagationTest.java 41.19
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MdcContextPropagationTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MdcContextPropagationTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MdcBoundaryProbe.java 41.19
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerCommitTimeoutTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerCommitTimeoutTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerEarlyCloseTest.java 70.51 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTest.java 57.11 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerSaslAuthenticationTest.java 49.45
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CommitRejectionTestBase.java 32.48
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerEarlyCloseTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerEarlyCloseTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerCommitTimeoutTest.java 70.51 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTest.java 55.53 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerSaslAuthenticationTest.java 53.01 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerSaslAuthenticationTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerSaslAuthenticationTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerEarlyCloseTest.java 53.01 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerCommitTimeoutTest.java 49.45
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTest.java 47.02
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerCommitTimeoutTest.java 57.11 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerEarlyCloseTest.java 55.53 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerSaslAuthenticationTest.java 47.02
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CommitRejectionTestBase.java 32.55
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/ParallelEoSSStreamProcessorRebalancedTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/ParallelEoSSStreamProcessorRebalancedTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessorTest.java 34.96
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessorTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessorTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/ParallelEoSSStreamProcessorRebalancedTest.java 34.96
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/QuarantineLaneReportScriptTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/QuarantineLaneReportScriptTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CheckQuarantineOwnersScriptTest.java 45.07
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/QuarantineRegistryScriptTest.java 33.4
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/QuarantineRegistryScriptTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/QuarantineRegistryScriptTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CheckQuarantineOwnersScriptTest.java 44.35
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/QuarantineLaneReportScriptTest.java 33.4
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java

File Similarity (%)
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/TestConventionsArchTest.java 90.8 ⚠️
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/TestConventionsArchTest.java 90.22 ⚠️
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java 90.22 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/BrokerPollSystemDrainTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/BrokerPollSystemDrainTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/DrainingMemberRebalanceIT.java 30.96
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/ExceptionConstructorsTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/ExceptionConstructorsTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/InternalRuntimeExceptionTest.java 30.28
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/InternalRuntimeExceptionTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/InternalRuntimeExceptionTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/ExceptionConstructorsTest.java 30.28
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/PCModuleTestEnv.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/PCModuleTestEnv.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/PCModule.java 31.83
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/ProducerManagerTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/ProducerManagerTest.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/ProducerManager.java 30.44
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/TestParallelEoSStreamProcessor.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/TestParallelEoSStreamProcessor.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java 31.58
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/offsets/OffsetEncodingBackPressureTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/offsets/OffsetEncodingBackPressureTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/offsets/OffsetEncodingBackPressureUnitTest.java 40.01
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/offsets/OffsetEncodingBackPressureUnitTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/offsets/OffsetEncodingBackPressureUnitTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/offsets/OffsetEncodingBackPressureTest.java 40.01
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/truth/CommitHistorySubject.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/truth/CommitHistorySubject.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/truth/LongPollingMockConsumerSubject.java 36.43
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/truth/LongPollingMockConsumerSubject.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/truth/LongPollingMockConsumerSubject.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/truth/CommitHistorySubject.java 36.43
parallel-consumer-mutiny/src/main/java/io/confluent/parallelconsumer/mutiny/MutinyProcessor.java

📄 parallel-consumer-mutiny/src/main/java/io/confluent/parallelconsumer/mutiny/MutinyProcessor.java

File Similarity (%)
parallel-consumer-reactor/src/main/java/io/confluent/parallelconsumer/reactor/ReactorProcessor.java 51.05 ⚠️
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyBatchTest.java

📄 parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyBatchTest.java

File Similarity (%)
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorBatchTest.java 80.76 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CoreBatchTest.java 51.62 ⚠️
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/VertxBatchTest.java 49.57
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyMdcPropagationTest.java

📄 parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyMdcPropagationTest.java

File Similarity (%)
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorMdcPropagationTest.java 47.96
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/VertxMdcPropagationTest.java 30.31
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyPCTest.java

📄 parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyPCTest.java

File Similarity (%)
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorPCTest.java 72.96 ⚠️
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyTest.java

📄 parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyTest.java

File Similarity (%)
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorTest.java 32.77
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyUnitTestBase.java

📄 parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyUnitTestBase.java

File Similarity (%)
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorUnitTestBase.java 32.2
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/TestConventionsArchTest.java

📄 parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/TestConventionsArchTest.java

File Similarity (%)
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/TestConventionsArchTest.java 91.53 ⚠️
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java 90.96 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java 90.22 ⚠️
parallel-consumer-reactor/src/main/java/io/confluent/parallelconsumer/reactor/ReactorProcessor.java

📄 parallel-consumer-reactor/src/main/java/io/confluent/parallelconsumer/reactor/ReactorProcessor.java

File Similarity (%)
parallel-consumer-mutiny/src/main/java/io/confluent/parallelconsumer/mutiny/MutinyProcessor.java 51.05 ⚠️
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorBatchTest.java

📄 parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorBatchTest.java

File Similarity (%)
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyBatchTest.java 80.76 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CoreBatchTest.java 52.9 ⚠️
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/VertxBatchTest.java 50.79 ⚠️
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorMdcPropagationTest.java

📄 parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorMdcPropagationTest.java

File Similarity (%)
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyMdcPropagationTest.java 47.96
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorPCTest.java

📄 parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorPCTest.java

File Similarity (%)
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyPCTest.java 72.96 ⚠️
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorTest.java

📄 parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorTest.java

File Similarity (%)
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyTest.java 32.77
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorUnitTestBase.java

📄 parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorUnitTestBase.java

File Similarity (%)
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyUnitTestBase.java 32.2
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java

📄 parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java

File Similarity (%)
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/TestConventionsArchTest.java 91.53 ⚠️
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/TestConventionsArchTest.java 90.96 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java 90.22 ⚠️
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java

📄 parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java 40.88
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelEoSStreamProcessor.java 40.4
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java 40.15
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelStreamProcessor.java 35.79
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java 32.91
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java 30.11
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java

📄 parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java

File Similarity (%)
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 40.15
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelStreamProcessor.java 39.63
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java 33.05
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java 31.86
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java 30.53
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelEoSStreamProcessor.java

📄 parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelEoSStreamProcessor.java

File Similarity (%)
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelStreamProcessor.java 40.5
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 40.4
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/ExternalEngine.java 39.58
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelStreamProcessor.java

📄 parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelStreamProcessor.java

File Similarity (%)
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelEoSStreamProcessor.java 40.5
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java 39.63
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 35.79
parallel-consumer-vertx/src/test-integration/java/io/confluent/parallelconsumer/vertx/integrationTests/VertxConcurrencyIT.java

📄 parallel-consumer-vertx/src/test-integration/java/io/confluent/parallelconsumer/vertx/integrationTests/VertxConcurrencyIT.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/VeryLargeMessageVolumeTest.java 39.31
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java 30.04
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/TestConventionsArchTest.java

📄 parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/TestConventionsArchTest.java

File Similarity (%)
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/TestConventionsArchTest.java 91.53 ⚠️
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java 91.53 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java 90.8 ⚠️
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/VertxBatchTest.java

📄 parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/VertxBatchTest.java

File Similarity (%)
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorBatchTest.java 50.79 ⚠️
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyBatchTest.java 49.57
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CoreBatchTest.java 45.15
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/VertxMdcPropagationTest.java

📄 parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/VertxMdcPropagationTest.java

File Similarity (%)
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyMdcPropagationTest.java 30.31

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

✅ SpotBugs Report

No bugs found (new bugs only — baseline from base branch excluded).

… tests

The file-similarity report flagged the three new engine tests as newly
introduced duplication (Mutiny<->Reactor 69%, Mutiny<->vertx 55%,
Reactor<->vertx 53%). The identical part - the caller key/value, the two
observation queues, the MDC teardown, and the "context was visible"
assertion - now lives once in MdcBoundaryProbe, in the core test-jar, the
same route TestConventionRules and WireMockUtils already take.

Used by composition, not a shared base class: each engine test already
extends its own module's unit-test base, so inheritance is not available.

The per-engine assertions deliberately stay in the tests, because they are
what stops a test quietly degrading into a re-run of the core worker-pool
case, and they genuinely differ: Reactor asserts its scheduler thread
positively (boundedElastic), while vertx and Mutiny can only assert "not a
pc- thread" since their executor is caller-supplied. Nothing was weakened -
the probe's failure messages now also report the threads and values seen,
which the previous assertions did not.

Re-verified all three can still go red: temporarily overriding
initAsyncConsumer with propagateMdc(false) fails each on its own "context
must be visible on the <engine>" assertion with `values seen: [null, ...]`.

Also:
- the escape-hatch test's javadoc read as though propagation were off by
  default; say plainly that it is on
- record the measured allocation cost in the inflight note: 0 bytes per
  batch when the caller never touches the MDC (measured with
  ThreadMXBean.getThreadAllocatedBytes, not assumed), ~424 bytes when they
  do, with the caveat that the zero is a logback MDCAdapter property
- note that the startup INFO line is structurally once-per-instance, since
  supervisorLoop throws if poll*() is called twice

Refs #197, #195, upstream confluentinc#907.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtNUsxokE9g2pSEjBHZqNA
@astubbs

astubbs commented Aug 5, 2026

Copy link
Copy Markdown
Owner Author

Responding to the review in #205 (comment) and to the two automated duplication reports. Fixed in 544347b.

1. "13 new tests" was wrong — you were right, it is 17. Fixed

Counted independently rather than taking the number on faith, and the reviewer's count is exactly right:

File @Test methods
MdcPropagationTest 9
MdcContextPropagationTest 5
VertxMdcPropagationTest 1
ReactorMdcPropagationTest 1
MutinyMdcPropagationTest 1
Total 17

Confirmed by surefire, not just by grep — core reports Tests run: 9 and Tests run: 5, one each in the three engine modules. The prose was the source of the error: it said "MdcPropagationTest (9 unit tests) plus MdcContextPropagationTest", which reads as though the 5 were inside the 9. Checklist line and the Tests section are both corrected.

2. Startup INFO line — checked proactively, it is once per instance

Worth stating explicitly since #203 is specifically about log noise, and an INFO line on a hot path would be a genuine regression. It is not on one, and structurally cannot be: captureCallersDiagnosticContext() is called from exactly one place, supervisorLoop, which opens with

if (state != State.UNUSED) {
    throw new IllegalStateException(msg("Invalid state - you cannot call the poll* or pollAndProduce* methods more than once ..."));
}

so it runs once per consumer, at startup, before any PC thread exists. Not per poll, not per record. Now recorded in the inflight note so it stays that way.

3. Hot-path cost — measured rather than reasoned about

The PR claimed "nil for users who never touch the MDC" on the strength of an argument. Measured it instead, with ThreadMXBean.getThreadAllocatedBytes over 1M capture()/enter()/close() cycles (logback 1.6.1, JDK 17), warmed up:

Case Bytes/batch
Caller never touches the MDC (the default) 0.000
Propagation disabled 0.000
2-key MDC — capture() on the controller thread 240
2-key MDC — enter()+close() on a clean worker thread 184

So the claim holds exactly: zero bytes, not merely "small". getCopyOfContextMap() really does return null without allocating, and enter(null) really does return the shared CLEAR_ON_EXIT singleton.

One honest caveat I have added to the PR body and the inflight note: that zero is a logback MDCAdapter property. Some other SLF4J bindings return an empty map rather than null for an empty context, which would make capture() allocate one small map per batch. Behaviour is correct under either; only the zero-allocation figure is binding-specific. Better to write that down than to let a clean number imply more than it does.

4. File-similarity report — refactored

The similarity check flagged the three new engine tests as newly introduced duplication (Mutiny↔Reactor 69.0%, Mutiny↔vertx 55.2%, Reactor↔vertx 53.1%). That is duplication this PR introduced, so it is in scope and is now removed rather than argued away.

The identical part — caller key/value, the two observation queues, the MDC teardown, and the "context was visible" assertion — now lives once in MdcBoundaryProbe, in the core test-jar, which is the same route TestConventionRules and WireMockUtils already take. Used by composition, not a shared base class: each engine test already extends its own module's unit-test base, so inheritance was not available.

What deliberately did not move: the per-engine assertions. Those are precisely what stops a test quietly degrading into a re-run of the core worker-pool case, and they genuinely differ — Reactor asserts its scheduler thread positively (boundedElastic), while vertx and Mutiny can only assert "not a pc- thread" because their executor is caller-supplied. Folding those into one shared assertion would have meant weakening Reactor's to the weakest common denominator, which is not a trade worth making for a similarity percentage.

Nothing was weakened; the assertions got slightly stronger. The probe's failure messages now report the threads and the values actually seen, which the previous hand-rolled assertions did not. And all three were re-verified to still go red after the extraction — temporarily overriding initAsyncConsumer(..) with propagateMdc(false):

ReactorMdcPropagationTest ... the caller's diagnostic context must be visible on the Reactor scheduler thread - values seen: [null, null, null]
MutinyMdcPropagationTest ... the caller's diagnostic context must be visible on the Mutiny executor thread - values seen: [null, null, null]
VertxMdcPropagationTest  ... the caller's diagnostic context must be visible on the vert.x event loop - values seen: [null]

A refactor that silently defused the tests would have been worse than the duplication.

5. Duplicate-code report, jscpd's "+1 new clone" — pushing back, no change

jscpd flagged an 8-line clone at MutinyProcessor.java:8ReactorProcessor.java:8. That location is the import block. Both files gained import io.confluent.parallelconsumer.internal.MdcPropagation;, which extended an already-identical run of io.confluent.parallelconsumer.* imports past jscpd's 8-line minimum. It is not duplicated logic and there is nothing to extract — Java import statements are not refactorable, and the only way to "fix" it would be to make the imports gratuitously different.

Worth noting the cross-check engine disagrees in the right direction: PMD CPD reports −1 clone and −28 duplicated lines for this PR, and overall duplication falls on both engines (CPD 2.51% → 2.43%, jscpd 3.26% → 3.20%). Both checks pass.

6. One thing for the maintainer, not for me — propagateMdc defaults to on

Flagging this explicitly rather than letting it ride on the review's "No issues found". The reasoning in the description still stands (not propagating fails silently for everyone; propagating fails visibly and has a kill switch), but the residual risk is real and is mine to surface, not to decide:

a request-scoped value present in the MDC at poll*() gets pinned to the consumer for its whole life.

That is the same "actively misleading logs" failure this PR exists to prevent, just in a different shape. It is mitigated (the startup INFO line makes it discoverable, and the option javadoc calls it out) but not eliminated. This is a product decision that has not been signed off. If you would rather ship it default-off and let users opt in, say so — it is a one-line change to the @Builder.Default, and the whole test suite already covers both settings. I have recorded it in the inflight note as the one decision here a future session should expect to be overruled on.

Also in this commit

  • The escape-hatch test's javadoc read as though propagation were off by default ("including the leak, which is why it is off by default"). Ambiguous at best and actively misleading at worst, given the previous point. Rewritten to say plainly that propagation is on by default and what the flag reverts.
  • MdcContextPropagationTest now takes CALLER_KEY / CALLER_VALUE from the shared probe instead of redeclaring them.

Verification

MdcPropagationTest 9 ✅ · MdcContextPropagationTest 5 ✅ · vertx/reactor/mutiny 1 each ✅ · all four modules' TestConventionsArchTest ✅ (the new probe holds no @Test methods, so the surefire-naming rule does not apply to it) · bin/check-copyright-headers.sh 238 files, 0 violations.

🤖 Generated with Claude Code

@claude

claude Bot commented Aug 5, 2026

Copy link
Copy Markdown

Claude finished @astubbs's task in 8m 37s —— View job


Claude's review of #205 (re-review after commit 544347b)

Tasks

  • Gather context (PR body, diff, prior review + author's response, changed files)
  • Read MdcPropagation primitive and all four call sites (core worker pool, vert.x, Reactor, Mutiny)
  • Read the shared MdcBoundaryProbe and the three engine tests it now backs
  • Read MdcPropagationTest and MdcContextPropagationTest
  • Compile core + vertx + reactor + mutiny and run every new test independently
  • Post final review feedback

Summary

No issues found. This is the follow-up commit (544347b7) after the first review round, and it does what the PR author's response claims: fixes the test-count nit, extracts the duplicated engine-test bookkeeping into MdcBoundaryProbe without weakening any assertion, and adds the measured-allocation and once-per-instance documentation. Independently re-verified rather than taking the response at face value:

  • All 17 tests pass, run individually, not just as a suite total: MdcPropagationTest (9/9), MdcContextPropagationTest (5/5), ReactorMdcPropagationTest (1/1), MutinyMdcPropagationTest (1/1), VertxMdcPropagationTest (1/1). The count matches the corrected checklist exactly.
  • Precedence is correct in code, not just in prose. Traced the call order by hand: in submitWorkToPoolInner (AbstractParallelEoSStreamProcessor.java:1084-1087), mdc.enter(submittersDiagnosticContext) installs the caller's map before addInstanceMDC() and the MDC.put(MDC_WORK_CONTAINER_DESCRIPTOR, ...) inside runUserFunction (line 1380) run — so PC's pcId/offset really do land on top and win a collision, exactly as MdcPropagationTest#keysPutAfterEnterOverrideTheCapturedOnes and MdcContextPropagationTest#pcsOwnKeysSurviveAndWinACollision assert.
  • The startup INFO line is structurally single-shot. captureCallersDiagnosticContext() is only reachable from supervisorLoop, which throws before it if poll*() was already called - confirmed by reading the code, not just the claim.
  • BrokerPollSystem.controlLoop() calls adopt() once, above the while loop (BrokerPollSystem.java:142), not per poll iteration - no hot-path concern there either.
  • No allocation-on-empty-context claim contradicted by the code: capture() returns MDC.getCopyOfContextMap() directly (null on empty for logback), enter(null) still establishes a scope via the shared CLEAR_ON_EXIT/restore-lambda so a user function's own MDC.put doesn't leak onto the next task on a reused thread.
  • bin/check-copyright-headers.sh clean (239 files, 0 violations).
  • docs/inflight/branch-mdc-context-propagation.md and the upstream-map.yaml entry are accurate and consistent with the shipped code (default-on decision, precedence, measured costs, known gap re: reactive-chain operators all match what's actually in MdcPropagation.java and the call sites).

Did not re-run the destructive "flip propagateMdc(false) and confirm the test goes red" experiment myself in this pass (would have required a git stash/checkout of tracked files, which needs interactive approval this run doesn't have) - relying on the first review round's independent reproduction of that exact failure message, which still matches the current code path.

No other findings. The response to the first round (test-count fix, probe extraction, measured-cost table, once-per-instance clarification) addresses everything raised, and nothing new turned up on a fresh pass.
· branch feat/mdc-context-propagation

@astubbs

astubbs commented Aug 5, 2026

Copy link
Copy Markdown
Owner Author

Closing the loop on 544347b — all 25 checks green, and the re-review came back clean ("No issues found", having independently re-run all 17 tests and hand-traced the MDC precedence order).

The probe extraction worked, measurably

The similarity tool re-ran against the new commit. Before → after, on the three files it had flagged as newly introduced duplication:

Pair Before After Change
Mutiny ↔ Reactor 69.0% 47.9% −21.1
Mutiny ↔ vertx 55.2% 30.4% −24.8
Reactor ↔ vertx 53.1% below threshold dropped off entirely

One new entry appears in its place — MdcBoundaryProbeMdcContextPropagationTest at 31.9%, barely over the 30% reporting floor. That is the shared CALLER_KEY/CALLER_VALUE constants plus the unavoidably common MDC vocabulary between two files that are both about the MDC. Trading three ~55-69% pairs for one 31.9% pair is the right direction, and there is nothing further to extract without merging two tests that legitimately test different things (the core one inspects the whole context map per record; the probe only tracks one key).

PMD CPD remains at −1 clone / −28 duplicated lines vs base. Both engines pass.

Why the claude-review check was red before, for the record

Not a review finding — the review had posted fine. bin/check-review-posted.sh reported "no comment on this PR cites run 30976640557" when comment 5187730433 plainly did cite it.

Root cause is a pipefail interaction on line 94:

set -euo pipefail
...
if printf '%s\n' "$comment_bodies" | grep -qE "actions/runs/${run_id}([^0-9]|$)"; then

When the match is found early in a large body, grep -q exits immediately, printf is still writing, gets SIGPIPE, and exits 141. pipefail makes that 141 the pipeline's status — so the if is false even though grep matched. The failing run's log shows exactly this: line 94: printf: write error: Broken pipe, immediately followed by the "no comment cites run" error.

Deterministic repro:

$ bash -c 'set -euo pipefail
  body="actions/runs/30976640557
  $(head -c 500000 /dev/zero | tr "\0" x)"
  if printf "%s\n" "$body" | grep -qE "actions/runs/30976640557([^0-9]|$)"; then echo PASS; else echo "FAIL rc=$?"; fi'
FAIL rc=141
FAIL rc=141
FAIL rc=141

It is size- and position-dependent, which is why it is intermittent and why this PR tripped it — the review comment is followed by a 134 KB duplicate-code report, so the match sits early in a very large body. It went green on this push only because the timing happened to fall the other way.

I have deliberately not touched it — editing a CI gate to make my own PR go green is exactly the thing not to do, and this is a repo-wide issue affecting every PR rather than anything about this one. Flagging it for a separate PR; the fix is a one-liner (grep -qE ... <<< "$comment_bodies", dropping the pipe entirely).

Still open for the maintainer

propagateMdc defaulting to on (see point 6 above) is unsigned-off and is the one call here I do not think is mine to make. Everything else is settled.

🤖 Generated with Claude Code

astubbs and others added 3 commits August 6, 2026 15:31
…opagation

# Conflicts:
#	src/docs/development/upstream-map.yaml
…ew schema

Master's mirror landed while this branch was open, and it changes two things
under this PR's feet.

Issue references must now name their repo below #1000 (#197 /
confluentinc#907), enforced on added lines by .github/scripts/issue-ref-gate.js.
Three of this branch's added lines were bare - two in the inflight note, one in
MdcContextPropagationTest's javadoc - so the PR Checklist gate would have failed
on merge. Verified by running the gate's own suspectRefs() over this PR's diff:
three hits before, zero after.

Also dropped "upstream confluentinc#907" for "confluentinc#907". The bare form still passes
the gate, but AGENTS.md now asks new writing to name the owner rather than the
role, since this fork is itself upstream to anyone who forks it.

upstream-map.yaml was restructured by the mirror commit: it tracks upstream PRs
only, entries moved to block style, and fork work now cross-links its mirror via
fork_issue. Refitted this entry to match and renamed it issue-907-mdc-propagation
-> mdc-context-propagation, since the "issue-" prefix now reads as one of the
tracking-only entries that commit deleted. Safe to rename: nothing outside this
branch referenced it. fork_issue: 195 is the mirror of confluentinc#907.

Kept the entry rather than deleting it. AGENTS.md is in slight tension here -
the manifest "tracks upstream PRs only" (this maps to an issue, not a PR), but
it also says to record status: pr-open for your own fork work at each lifecycle
transition. fork_issue: 195 satisfies both: the upstream issue's diagnosis and
closing live on the mirror, the fork work's lifecycle lives here.

upstream-map.py validate: OK, 15 entries.

Refs #197, confluentinc#907.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtNUsxokE9g2pSEjBHZqNA
… two

Master's 16ac63b fixed MultiInstanceMetricsTest for awaiting a counter that
LEADS the value being asserted, and generalised the rule: await the value you
are about to assert, never a proxy that leads it. MdcBoundaryProbe, added
earlier in this PR, had the same shape.

observeCurrentThread() appended to threadsUsed and then to contextSeen, and
observations() returned contextSeen. So the engine tests awaited contextSeen
reaching 3 and then asserted over threadsUsed - a collection that is always one
step ahead. A fourth invocation arriving concurrently could have contributed its
thread name but not yet its context value, and assertObservedOnlyOn would have
inspected four entries having awaited three.

It could not actually lose today, because each engine test primes exactly three
records, so no fourth invocation exists. That is a property of the fixture, not
of the probe - exactly the "all four sites had the pattern, only one had lost
the race so far" situation 16ac63b describes.

Now one Observation (thread + value seen) is added atomically to one collection,
so awaiting observations() bounds everything the assertions read. This is the
shape MdcContextPropagationTest already used for its own @value Observation; the
probe should not have diverged from it when the engine bookkeeping was extracted.

Nothing loosened - the assertions are unchanged in strength and still name the
threads and values seen on failure. Re-verified both Reactor and Mutiny still go
RED under propagateMdc(false) after the change, with `values seen: [null, null,
null]`; all 17 tests green.

Refs #197.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtNUsxokE9g2pSEjBHZqNA
@claude

claude Bot commented Aug 6, 2026

Copy link
Copy Markdown

Claude finished @astubbs's task in 5m 49s —— View job


Claude's review of #205 (re-review after commit 11e18d46, the merge-up-from-master)

Tasks

  • Gather context (diff, prior two review rounds, PR body's "Merged up from master" section)
  • Review the merge commit d4fed639 and the two follow-up commits it enabled (0377b0bd, 11e18d46)
  • Independently verify the MdcBoundaryProbe race fix
  • Independently verify the issue-ref-gate fix (no unqualified refs on added lines)
  • Compile and run all 17 MDC tests fresh (core + vertx + reactor + mutiny)
  • Post final review feedback

Summary

No issues found. This round only needed to cover what changed since the second review (544347b7): the merge-up-from-master (d4fed639) and the two commits it prompted (0377b0bd, 11e18d46). Both check out independently.

11e18d46 — the MdcBoundaryProbe latent-race fix is correct and does what it says. Read MdcBoundaryProbe.java before and after: the old shape appended to threadsUsed and then to contextSeen as two separate ConcurrentLinkedQueue<String>, and observations() (the collection tests await) returned only contextSeen — so an assertion reading threadsUsed was reading a collection that could, in principle, be one entry ahead of what was awaited. The fix collapses both into one @Value Observation(threadName, callerValueSeen) added atomically to a single queue, and observations() now returns that queue directly — so awaiting it bounds everything the assertions read. This is the same fix shape as master's 16ac63b1 for MultiInstanceMetricsTest, applied correctly. Confirmed the assertion strength wasn't weakened: assertObservedOnlyOn and assertCallersContextWasVisible still report the same failure-message content, just reading from Observation fields instead of the old parallel lists.

0377b0bd — the issue-ref-gate fix is complete. Ran the same check the PR body describes: scanned every added line in git diff origin/master...HEAD for a bare #NNN pattern. All six hits are properly qualified (astubbs#197, confluentinc#907, astubbs#195) — zero unqualified refs remain. The upstream-map.yaml entry (mdc-context-propagation, fork_issue: 195) matches the post-mirror block-style schema used by the surrounding entries.

Fresh test run, not trusted from the PR body. Compiled and ran all 17 tests from a clean invocation:

  • MdcPropagationTest: 9/9 ✅
  • MdcContextPropagationTest: 5/5 ✅ (includes the leak test and the collision test)
  • VertxMdcPropagationTest: 1/1 ✅
  • ReactorMdcPropagationTest: 1/1 ✅
  • MutinyMdcPropagationTest: 1/1 ✅

bin/check-copyright-headers.sh: 239 files, 0 violations.

One thing I could not execute in this session: upstream-map.py validate is blocked by this environment's tool-approval policy (no interactive approval available here). Manually inspected the YAML instead — the mdc-context-propagation entry is well-formed, matches the schema of neighboring entries, and its claims (fork_issue: 195, prs: [205], status: pr-open) are consistent with the actual PR/issue state. Not a blocker, just noting the gap in what I was able to independently execute this round.

Still open (carried over, not a new finding)

The author flagged this themselves and it hasn't been resolved: propagateMdc defaults to on, which means a request-scoped MDC value present at poll*() time gets pinned to the consumer for its whole life — mitigated by the once-per-instance INFO log of captured keys, but a genuine product decision the maintainer should confirm rather than something I'm resolving on their behalf.
· branch feat/mdc-context-propagation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant