Skip to content

fix(core) #177: report the poll thread's real error, not the commit-response timeout - #204

Open
astubbs wants to merge 9 commits into
masterfrom
test/177-commit-response-timeout
Open

fix(core) #177: report the poll thread's real error, not the commit-response timeout#204
astubbs wants to merge 9 commits into
masterfrom
test/177-commit-response-timeout

Conversation

@astubbs

@astubbs astubbs commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Description

Closes the reader-facing half of #177 (confluentinc/parallel-consumer#833): InternalRuntimeException: Timeout waiting for commit response PT30S, reported on 0.5.3.1 with ~50% of records failing across 1000 keys.

This started as a verification task, and the triage it was checking was half right.

The prior pass concluded the bug was already fixed on master by #100/#108, just unreleased. That is confirmed for the trigger: with the RebalanceInProgressException catch removed from ConsumerOffsetCommitter.commitDeferringOnRebalance(), the reported chain reproduces verbatim, message and all.

But it is not the whole bug. The broker-poll thread is the only producer of commit responses, so any exception that kills it turns every later sync commit into that same message — one that names neither the failing subsystem nor the failure. #100/#108 removed two ways to kill that thread. Broker down, offset encoding and authorization still produced the identical unactionable error, and fixing exceptions one at a time was never going to close that class.

What changed

AbstractParallelEoSStreamProcessor — supervise the poller when a commit fails, so the poller's actual exception becomes the reported cause, with the commit timeout retained as suppressed. Neither is lost.

This had to go on the commit failure path. Supervising earlier in controlLoop() is the obvious move, was tried, was measured, and does nothing: the poller dies while servicing the commit the control thread is already blocked on, so that thread never reaches the top of the loop. Recorded as falsified in docs/inflight/ so nobody retries it.

ConsumerOffsetCommitter — the message interpolated the unrelated constant DEFAULT_TIMEOUT, so it claimed PT30S regardless of how offsetCommitTimeout was configured, overstating the shipped default (10s) by 3x. The reporter's PT30S therefore told us nothing about their settings. It now reports the timeout actually waited, and says what a timeout here usually means.

ConsumerManager.commitSync — the retry budget was captured inside the retry loop, so every attempt reset it. Whenever an attempt failed faster than the budget the comparison could never become false, and it retried forever with no backoff — measured at 51 attempts against a 500ms budget. PC then neither committed nor failed: the poll thread was stranded inside one commitSync while the control thread waited out its commit response. That is this same bug arriving from the broker-down direction instead of the rebalance one, which is why it is in this PR rather than a separate one.

poll() captures pollStarted outside its retry loop for the very same SASL budget — the same knob, in the same class, done correctly. That is the strongest evidence the difference was accidental rather than designed.

Direction of this behaviour change, stated plainly: it makes PC give up where it previously hung. There is no case where PC now keeps running somewhere it previously stopped. The budget is per commitSync call (per commit cycle), not per PC lifetime, so each commit still gets its full configured budget. The honest cost: a broker outage longer than offsetCommitTimeout where a later attempt would have succeeded now shuts PC down instead of retrying indefinitely — which is exactly what the option asks for, and an unbounded silent retry is worse for a library than a loud failure.

Evidence the tests actually catch it

Every test was confirmed discriminating by reverting the fix and watching it fail — a test that passes both ways proves nothing.

Revert Test Result
RebalanceInProgressException catch CommitResponseTimeoutSymptomTest#aRebalanceStormUnderAHighFailureRateNeitherStallsNorKillsTheConsumer dies with the reported message after 123s; green in 3.4s with the fix
supervise-on-commit-failure CommitResponseTimeoutSymptomTest#aDeadPollThreadReportsItsOwnCauseNotTheCommitResponseTimeout real cause absent from the chain entirely
startedTime back inside the loop ConsumerManagerCommitRetryBudgetTest 51 attempts against a 500ms budget, never throws

CommitResponseTimeoutSymptomTest reproduces the reported workload rather than a minimal one: 1000 keys, ~50% failing, KEY ordering, and rejections recurring for the whole run instead of only at start-up — fed over time, because the report is of a consumer that "runs for a while". An earlier single-batch version drained in 4 commit cycles and saw 1 rejection, which is not a storm; it now runs 20 cycles with 6 deferrals. A fix that deferred a commit but never re-requested one passes the existing CommitRejectionTestBase and stalls here.

It is deliberately not a subclass of CommitRejectionTestBase — that base pins a different property (offsets not recorded as successful, one rejection reason, rejected only at start-up) on a workload chosen to isolate it. The reasoning is in the class javadoc.

ConsumerManagerCommitRetryBudgetTest bounds attempts rather than hanging when the budget is not enforced, so an unbounded regression fails instead of wedging CI.

Deliberately not done

Releasing waiters at the moment the poller dies, rather than after offsetCommitTimeout. That needs new cross-thread liveness state (the setCloseInProgressSignal pattern is the precedent), and the diagnosis is already correct without it. Recorded in docs/inflight/bug-177-commit-response-timeout.md.

Verified: full unit suite green across all 11 modules; core 321 tests, 0 failures. Copyright scanner clean.

Updated from master

Merged origin/master cleanly (no conflicts). Three things on master bore on this branch:

The issue-reference gate (735b1d3a, #114) fails a bare #NN below 1000 on added lines, because the fork's numbers sit entirely inside confluentinc's range. This branch added 12 such references across javadoc, both new tests, and the inflight note; all are now owner-qualified (astubbs#177, confluentinc#833, …). astubbs#177 is itself the mirror of confluentinc#833, so the pair reads correctly. // fixes github issue #809 was left alone — a pre-existing line, not one this PR adds.

The SIGPIPE bug this PR diagnosed is fixed on master (cb8b1182) and now guarded repo-wide (7586b8c7), with the herestring fix suggested here. Two consequences: the claude-review red this PR spent a pass diagnosing is gone at the root, and docs/inflight/ci-review-agent.md has been rewritten from "needs its own PR" to resolved, keeping the measurements and the lesson.

Worth noting, since cb8b1182 called check-quarantine-owners.sh latent with "351 bytes of headroom on a file two open PRs are adding lines to"this is one of those PRs, and it takes AbstractParallelEoSStreamProcessor.java to 67,168 bytes, 1,632 past the 64 KiB buffer. Without that fix this branch would have failed as "annotation missing", pointing nowhere near the cause.

16ac63b1 ("await the metric, not a counter that leads it") does apply here, and found one real site. Details below.

Applying 16ac63b1's rule to these tests

The rule — await the value you are about to assert, never a proxy that leads it — landed while this PR was open. Both directions turned out to be present in CommitResponseTimeoutSymptomTest, which makes the distinction concrete, so it is recorded as a third instance in the existing write-up rather than a new file.

  • One genuine instance, fixed. The test awaited a Set populated inside the user function, then read a rejection counter incremented on the broker-poll thread. Two threads, neither ordering the other. The margin is large — feeding spans tens of commit intervals — but that is what a latent race looks like until it loses. Now awaited on the value actually asserted. Nothing is masked: if the rejections never arrive, it still fails.
  • One that is already the safe direction, and must stay. Awaiting isClosedOrFailed() then asserting getFailureCause() is sound because supervisorLoop() assigns failureReason before doClose() sets state=CLOSED and before the throw that completes the future — so the awaited signal lags the asserted value. Converting it to await a non-null cause would be a real loss of strength, since a null cause is exactly what a regression here produces. Commented at the site so nobody "fixes" it.

Discriminating power is unaffected: the reverting evidence below still holds, because the first await (succeeded.hasSize(KEYS)) is unchanged and comes first.

Checklist

  • Docs updated - docs/inflight/bug-177-commit-response-timeout.md (including the falsified approach), src/docs/development/upstream-map.yaml entry bug-833-commit-response-timeout (prs: [204] / status: pr-open, fork_issue: 177; dropped the now-dead forwarded:/todo: fields after master removed the tooling that read them), docs/inflight/ci-review-agent.md (rewritten as resolved), docs/solutions/test-flakiness/vacuous-await-condition-brokerpoller-backpressure-2026-07-31.md (third instance), and javadoc on each changed method. CHANGELOG.adoc deliberately untouched per AGENTS.md (generated at release time, not a per-PR chore)
  • Tests added/updated - two new test classes, each demonstrated to fail against the unfixed code
  • Title & body reflect the final content of this PR
  • N/A - no CI runners or workflows touched

Relates to #177 and confluentinc/parallel-consumer#833. Same family as #100 / #108 (confluentinc#857).

🤖 Generated with Claude Code

https://claude.ai/code/session_01RtNUsxokE9g2pSEjBHZqNA

…esponse timeout

"InternalRuntimeException: Timeout waiting for commit response" is what users
report (#177, upstream confluentinc#833). It is a symptom. The broker-poll thread is the
only producer of commit responses, so when it dies every later sync commit
waits out offsetCommitTimeout and throws a message naming neither the failing
subsystem nor the failure.

Verified first, then fixed. The triage that called this already-fixed-unreleased
by #100/#108 is right about the TRIGGER: with the RebalanceInProgressException
catch removed, the reported chain reproduces exactly. But those PRs removed two
ways to kill that thread, not the misleading symptom - broker down, offset
encoding and authorization all still produced it, and fixing exceptions one at a
time was never going to close that.

- AbstractParallelEoSStreamProcessor: supervise the poller when a commit fails,
  so its actual exception becomes the reported cause and the commit timeout is
  retained as suppressed. Neither is lost. This had to go on the commit FAILURE
  path: supervising earlier in controlLoop() was tried and measured, and does
  nothing, because the poller dies while servicing the commit the control thread
  is already blocked on, so that thread never reaches the top of the loop.

- ConsumerOffsetCommitter: the message interpolated the unrelated constant
  DEFAULT_TIMEOUT, so it claimed PT30S no matter how offsetCommitTimeout was
  configured - overstating the shipped default by 3x. The reporter's "PT30S"
  therefore said nothing about their settings. Report the timeout actually
  waited, and say what a timeout here usually means.

- ConsumerManager.commitSync: the retry budget was captured INSIDE the retry
  loop, so every attempt reset it. Whenever an attempt failed faster than the
  budget the comparison could never become false and it retried forever with no
  backoff - measured at 51 attempts against a 500ms budget. PC then neither
  committed nor failed: the poll thread was stranded inside one commitSync while
  the control thread waited out its commit response, which is this same bug
  arriving from the broker-down direction rather than the rebalance one. Capture
  it once per call, matching poll()'s pollStarted - the same budget in the same
  class, done correctly, which is the strongest evidence the difference was
  accidental. This makes PC give up where it previously hung; it does not make
  it keep running anywhere it previously stopped.

Tests, each confirmed discriminating by reverting the fix and watching it fail:

- CommitResponseTimeoutSymptomTest reproduces the reported workload - 1000 keys,
  ~50% failing, KEY ordering, rejections recurring for the whole run rather than
  only at start-up, fed over time because the report is of a consumer that runs
  for a while. Without the catch it dies with the reported message after 123s;
  with it, 20 commit cycles and 6 deferrals and a full drain in 3.4s. Its second
  test pins the diagnosability half: without the supervise path the real cause
  is absent from the chain entirely.
- ConsumerManagerCommitRetryBudgetTest bounds attempts rather than hanging when
  the budget is not enforced, so the unbounded case fails instead of wedging CI.

Deliberately NOT done, recorded in docs/inflight: releasing waiters at the
moment the poller dies, rather than after offsetCommitTimeout. That needs new
cross-thread liveness state, and the diagnosis is already correct without it.

Verified: full unit suite green, 11 modules; core 321 tests.

Upstream-Issue: confluentinc#833
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 finished @astubbs's task in 8m 44s —— View job


Claude finished the review

Tasks

  • Gather context (PR body, diff, changed files)
  • Read repo AGENTS.md / docs/inflight conventions
  • Review changed source files (AbstractParallelEoSStreamProcessor, ConsumerManager, ConsumerOffsetCommitter)
  • Review new tests (CommitResponseTimeoutSymptomTest, ConsumerManagerCommitRetryBudgetTest)
  • Verify regression claims by reverting each fix and confirming RED, then GREEN again
  • Post final review

Summary

This is a well-diagnosed, well-tested fix. I verified the two central claims directly rather than trusting the PR body:

  • Reverted commitOffsetsThatAreReady()commitOffsetsReportingPollerDeath() at AbstractParallelEoSStreamProcessor.java:890 and re-ran CommitResponseTimeoutSymptomTest#aDeadPollThreadReportsItsOwnCauseNotTheCommitResponseTimeoutfails exactly as claimed (AuthorizationException absent from the chain). Restored, and the full class (2 tests) passes green in ~5.7s.
  • Reverted the startedTime hoist in ConsumerManager.commitSync back inside the retry loop and re-ran ConsumerManagerCommitRetryBudgetTestfails, logging exactly 51 attempts against the 500ms budget without ever throwing, matching the PR's own measurement. Restored, and the test passes green.
  • Also ran the adjacent pre-existing commit/timeout tests (MockConsumerCommitFailedTest, MockConsumerCommitTimeoutTest, PartitionStateCommittedOffsetTest) — all 7 pass, no regressions.
  • bin/check-copyright-headers.sh — clean, 0 violations (the Confluent-derived-file Modifications Copyright lines were added correctly on the two modified upstream files).

Design review

  • commitOffsetsReportingPollerDeath() (AbstractParallelEoSStreamProcessor.java:945-958) is correctly scoped: it only intercepts InternalRuntimeException (unchecked, matches the commit-timeout throw site), so a healthy poller leaves the original commit failure untouched, and a genuinely dead poller supersedes it with the real cause while retaining the commit failure as suppressed. The javadoc's claim that supervising earlier in controlLoop() doesn't help checks out from reading the loop: the pre-existing brokerPollSubsystem.supervise() call at line 911 is unreachable in the hang case because commitOffsetsReportingPollerDeath() at line 890 blocks/throws first.
  • ConsumerOffsetCommitter.commitAndWait() now reports the timeout actually waited (commitTimeout) instead of the unrelated DEFAULT_TIMEOUT constant — confirmed DEFAULT_TIMEOUT is still used elsewhere (BrokerPollSystem.java) so nothing is orphaned.
  • ConsumerManager.commitSync's startedTime hoist is a clean one-line fix for a real unbounded-retry bug, and mirrors poll()'s existing (correct) pattern for pollStarted.

Minor, non-blocking

No correctness issues found. The fix is narrowly scoped, the tests are genuinely discriminating (verified, not just claimed), and documentation/AGENTS.md conventions are followed correctly aside from the one stale manifest field noted above.

@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 28 28 ➖ 0
Duplicated lines 850 850 ➖ 0
Duplication 2.46% 2.46% ➖ 0
Rule Limit Status
Max duplication 5% ✅ Pass (2.46%)
Max increase vs base +0.1% ✅ Pass (+0.00%)

No new clones introduced by this PR.

✅ jscpd (language-agnostic)

PR Base Change
Clones 77 75 🫤 +2
Duplicated lines 1101 1087 :face_with_monocle: +14
Duplication 3.23% 3.23% ➖ 0
Rule Limit Status
Max duplication 5% ✅ Pass (3.23%)
Max increase vs base +0.1% ✅ Pass (+0.00%)
⚠️ 2 new clones introduced
  • 9 lines: parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerCommitTimeoutTest.java:9 <-> parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/ConsumerManagerCommitRetryBudgetTest.java:7
  • 7 lines: parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CommitRejectionTestBase.java:7 <-> parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CommitResponseTimeoutSymptomTest.java:8

Powered by astubbs/duplicate-code-cross-check

@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-core/src/test/java/io/confluent/parallelconsumer/CommitRejectionTestBase.java parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CommitResponseTimeoutSymptomTest.java 39.8
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CommitResponseTimeoutSymptomTest.java parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerCommitTimeoutTest.java 34.8
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CommitResponseTimeoutSymptomTest.java parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTest.java 31.8
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CommitResponseTimeoutSymptomTest.java parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerEarlyCloseTest.java 30.6

🔺 Increased similarities

File A File B Base (%) PR (%) Change
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CommitRejectionTestBase.java parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTest.java 32.5 32.8 +0.3
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/BrokerPollSystem.java 33.3 33.6 +0.2
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/ChaosScenarioBase.java 38.0 38.2 +0.1
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContext.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/RecordContextInternal.java 35.5 35.6 +0.1
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/ChaosChurnStormIT.java 48.8 48.9 +0.1
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java 45.5 45.6 +0.1
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyUnitTestBase.java parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorUnitTestBase.java 32.1 32.2 +0.1
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/ExceptionConstructorsTest.java parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/InternalRuntimeExceptionTest.java 30.1 30.1 +0.1
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/KafkaSanityTests.java parallel-consumer-core/src/test/java/io/confluent/csid/utils/LoopingResumingIteratorTest.java 34.0 34.1 +0.1
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/ParallelEoSSStreamProcessorRebalancedTest.java parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessorTest.java 34.7 34.7 +0.1
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java 32.6 32.6 +0.0
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CommitRejectionTestBase.java parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerCommitTimeoutTest.java 32.4 32.5 +0.0
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceHighVolumeTest.java parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java 46.9 47.0 +0.0
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java 37.0 37.0 +0.0
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 34.38
parallel-consumer-core/src/test/java/io/confluent/csid/utils/CollectionUtils.java 32.29
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 38.68
parallel-consumer-core/src/main/java/io/confluent/csid/utils/Java8StreamUtils.java 34.38
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.13 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 39.9
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PCRetriableException.java 36.64
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 36.51
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 34.97
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 34.97
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 34.89
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 33.64
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 60.88 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java 54.74 ⚠️
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 40.31
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java 37.03
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java 32.57
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java 31.33
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 60.88 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java 50.57 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java 36.7
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 32.33
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java 31.48
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java 30.07
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.64
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 32.93
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.13 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 52.85 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 44.44
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 34.5
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 33.16
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 30.61
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 30.61
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalRuntimeException.java 30.58
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.12
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 54.74 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java 50.57 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java 45.56
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java 33.84
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java 32.64
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/TestParallelEoSStreamProcessor.java 31.05
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.56
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java 37.03
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java 36.7
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java 32.62
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.56
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java 32.2
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 33.84
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/RecordContextInternal.java 33.03
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java 32.57
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContext.java 32.2
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java 31.48
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.56
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java 33.03
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.58
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java 32.64
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.58
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.49
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.24 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 52.85 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 50.58 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java 48.62
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 39.9
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalRuntimeException.java 39.3
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 36.76
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 33.49
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 33.49
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PCRetriableException.java 32.93
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.3
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 31.21
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 30.58
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 32.46
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.12
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/ProducerManagerTest.java 30.46
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.3 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 37.29
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 37.29
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 36.76
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 34.89
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 34.5
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 32.4
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.24 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 51.3 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 48.03
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 46.98
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 46.98
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java 46.51
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 44.44
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 36.51
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalRuntimeException.java 31.21
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.62
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 46.51
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 45.12
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 37.77
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 37.77
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.58 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 48.03
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java 45.12
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 33.64
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 33.16
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 32.4
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 31.27
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 31.27
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.98
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java 37.77
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 37.29
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 34.97
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 33.49
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 31.27
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 30.61
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.98
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java 37.77
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 37.29
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 34.97
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 33.49
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 31.27
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 30.61
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.3
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.3
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/PartitionState.java 30.3
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.29
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.29
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.3
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.38
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.87
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 34.09
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.43 ⚠️
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java 46.95
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceRebalanceTest.java 38.61
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.1
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java 41.11
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceHighVolumeTest.java 38.61
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.32
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.32
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.67 ⚠️
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceHighVolumeTest.java 46.95
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceRebalanceTest.java 41.11
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.67 ⚠️
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceHighVolumeTest.java 55.43 ⚠️
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceRebalanceTest.java 44.1
parallel-consumer-vertx/src/test-integration/java/io/confluent/parallelconsumer/vertx/integrationTests/VertxConcurrencyIT.java 39.11
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.86
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.86
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/chaostests/ChaosScenarioBase.java 38.16
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkIT.java 30.04
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.54
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.54
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/ChaosChurnStormIT.java 30.04
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 38.16
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.38
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 38.68
parallel-consumer-core/src/main/java/io/confluent/csid/utils/Java8StreamUtils.java 32.29
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 34.09
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.49
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.0
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/QuarantineRegistryScriptTest.java 44.25
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/CommitResponseTimeoutSymptomTest.java 39.83
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTest.java 32.82
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerCommitTimeoutTest.java 32.47
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CommitResponseTimeoutSymptomTest.java

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

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CommitRejectionTestBase.java 39.83
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerCommitTimeoutTest.java 34.78
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTest.java 31.82
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerEarlyCloseTest.java 30.63
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.05 ⚠️
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyBatchTest.java 50.74 ⚠️
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/VertxBatchTest.java 44.82
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/BatchTestBase.java 30.49
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 69.85 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTest.java 56.36 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerSaslAuthenticationTest.java 49.3
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CommitResponseTimeoutSymptomTest.java 34.78
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CommitRejectionTestBase.java 32.47
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 69.85 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTest.java 54.37 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerSaslAuthenticationTest.java 52.71 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CommitResponseTimeoutSymptomTest.java 30.63
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 52.71 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerCommitTimeoutTest.java 49.3
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTest.java 46.28
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 56.36 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerEarlyCloseTest.java 54.37 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerSaslAuthenticationTest.java 46.28
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CommitRejectionTestBase.java 32.82
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CommitResponseTimeoutSymptomTest.java 31.82
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.74
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.74
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.0
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/QuarantineRegistryScriptTest.java 33.35
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.25
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/QuarantineLaneReportScriptTest.java 33.35
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.31 ⚠️
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/TestConventionsArchTest.java 89.64 ⚠️
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java 89.64 ⚠️
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.87
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.15
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.15
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 32.46
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.46
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.05
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 39.92
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 39.92
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.34
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.34
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.93 ⚠️
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 78.89 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CoreBatchTest.java 50.74 ⚠️
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/VertxBatchTest.java 48.88
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 71.16 ⚠️
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.22
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.24
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.08 ⚠️
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java 90.4 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java 89.64 ⚠️
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.93 ⚠️
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 78.89 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CoreBatchTest.java 52.05 ⚠️
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/VertxBatchTest.java 50.14 ⚠️
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 71.16 ⚠️
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.22
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.24
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.08 ⚠️
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/TestConventionsArchTest.java 90.4 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java 89.64 ⚠️
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-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelEoSStreamProcessor.java 41.41
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java 40.31
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java 39.74
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelStreamProcessor.java 35.28
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java 32.33
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 39.74
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelStreamProcessor.java 39.26
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java 32.62
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java 31.33
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java 30.07
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 41.56
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 41.41
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/ExternalEngine.java 39.49
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 41.56
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java 39.26
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 35.28
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.11
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.08 ⚠️
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java 91.08 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java 90.31 ⚠️
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.14 ⚠️
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyBatchTest.java 48.88
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CoreBatchTest.java 44.82

@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).

The entry was written when the work was still on a branch, so it claimed
`prs: []` / `status: in-progress` while PR #204 was open against it. AGENTS.md
requires the transition in the same commit that causes it, precisely because
nothing automated catches this: `upstream-map.py validate` only checks the
schema, so a manifest that says `prs: []` with a live fork PR passes every gate
and rots silently - the same drift a 2026-08-04 audit found in five entries.

Raised by the automated review on #204.

Upstream-Issue: confluentinc#833
@astubbs

astubbs commented Aug 5, 2026

Copy link
Copy Markdown
Owner Author

Review response

Addressing the automated review, the two duplication reports, and the red claude-review check. (The review landed as a single top-level comment rather than inline threads, so there is nothing to reply in-thread to - this is the response to all of it in one place.)

1. Stale manifest entry — valid, fixed in 70a1f1a

Correct finding, and AGENTS.md mandates it explicitly:

Update the entry at every lifecycle transition of your own work, in the same commit that causes it: opening a PR (prs: + status: pr-open) …

bug-833-commit-response-timeout now reads prs: [204] / status: pr-open. scripts/upstream-map.py validateOK: 25 entries, no schema errors.

This is exactly the drift the AGENTS.md note warns about — validate only checks the schema, so prs: [] with a live fork PR passes every gate and rots silently.

2. Duplicate-code report — 2 new clones, both import preambles. No refactor.

Both flagged clones are the mandatory Java header/import block, not logic:

  • 9 lines, MockConsumerCommitTimeoutTestConsumerManagerCommitRetryBudgetTest — the run MockConsumer, OffsetAndMetadata, OffsetResetStrategy, TopicPartition, TimeoutException, Test, Timeout, blank, java.time.Duration. Seven consecutive import lines, a blank, and one more import.
  • 7 lines, CommitRejectionTestBaseCommitResponseTimeoutSymptomTest — likewise inside the import block.

Two tests that both drive a MockConsumer and both assert with Truth cannot avoid importing the same seven types. There is no extractable behaviour here, and de-duplicating imports is not a thing. PMD CPD agrees there is nothing new (29 → 29 clones, +0.00%), and jscpd's own gate passes at +0.00%.

3. File-similarity report — pushing back on the 39.7%

CommitResponseTimeoutSymptomTestCommitRejectionTestBase at 39.7% is the similarity tool measuring identifier overlap, and every commit-path test in this module shares the same vocabulary (MockConsumer, TopicPartition, OffsetAndMetadata, ParallelConsumerOptions, commitSync, PERIODIC_CONSUMER_SYNC, Awaitility). The same report puts CommitRejectionTestBaseMockConsumerTest at 32.8% on the base branch, with no shared code at all — that is the tool's floor for this package, not a signal.

The classes are not the same test:

CommitRejectionTestBase CommitResponseTimeoutSymptomTest
Workload 10 records, 1 key, 1 partition, no retries 1000 keys, 4 partitions, ~50% failing, KEY ordering
Rejections first 3 only, at start-up every 3rd commit, for the whole run
Feeding one batch 20 batches over time
Property pinned offsets not recorded as successful consumer neither stalls nor dies; poller's real cause is reported

Merging them would mean parameterising the base over workload, feed strategy, rejection schedule and assertion set — four axes to save an import block and a MockConsumer subclass. That is the abstraction costing more than the duplication. The rationale is already in the class javadoc so the next person does not re-litigate it, and specifically: a fix that defers a commit but never re-requests one passes the base and stalls here, which is why the second test has to exist separately.

4. The red claude-review check is a bug in the gate, not a missing review

I have not touched the gate, and I am not going to — a CI gate edited by the PR it is blocking is worthless. Flagging it for a separate fix.

The review was posted and does cite its run id. bin/check-review-posted.sh:94 is:

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

with set -euo pipefail in force. grep -q exits the moment it matches. If printf still has unwritten data, it takes EPIPE, and bash's builtin printf reports write error: Broken pipe and returns non-zero — which pipefail then propagates as the pipeline's status. The if is false, and the script reports "no review posted" because the review was found early. The CI log shows the tell:

bin/check-review-posted.sh: line 94: printf: write error: Broken pipe
##[error]The review step reported success but posted no review...

It is deterministic on payload size — the 64 KiB pipe buffer. Replayed locally against this PR's real comment payload:

bytes=1000    runid=present  gate=PASS
bytes=60000   runid=present  gate=PASS
bytes=65536   runid=present  gate=PASS      <- 64 KiB
bytes=70000   runid=present  gate=FAIL
bytes=137704  runid=present  gate=FAIL      <- this PR, in full

Under 64 KiB printf completes its write before grep reads and there is no EPIPE; over it, printf blocks mid-write and grep short-circuits out from under it. This PR's comments total ~137 KB, mostly the file-similarity report's expandable section.

Two consequences worth having on record:

  1. The failure mode is backwards. The gate is most likely to fail when the reviewer is working and the PR is busy — a match found early in a large payload is precisely the failing shape. A PR with no review has a small payload and grep reading to EOF, so no EPIPE and no false alarm from this path.
  2. It gets worse over a PR's life, because comment payloads only grow.

The error message compounds it by asserting a cause that is not true here — this PR touches no workflow file (git diff --name-only a4db924a..HEAD -- .github/ bin/ is empty), so the workflow-validation guard is not involved.

Fix belongs in its own PR; something along the lines of dropping the pipe (grep -qE … <<<"$comment_bodies") so there is no EPIPE to trip over. Happy to open it if wanted.

5. Flagging for maintainer decision: the ConsumerManager.commitSync behaviour change

The review endorsed this ("a clean one-line fix for a real unbounded-retry bug") and did not challenge it, so I want to raise it rather than let silence stand in for sign-off.

The honest cost, restated: a broker outage longer than offsetCommitTimeout, where a later attempt would have succeeded, now shuts PC down instead of retrying indefinitely. That is a real behaviour change for anyone relying on the old (unintended) unbounded retry.

The case for it: the code contradicted its own comment and could not honour the option it named; poll() captures its budget outside its loop for the same SASL knob in the same class; and the change makes PC give up where it previously hung — there is no configuration where it now keeps running somewhere it previously stopped. The budget is per commitSync call, not per lifetime.

Still: it is a behaviour change riding along with a diagnostics fix. If you would rather it were split out, or made opt-in, say so and I will do that rather than have it merge on the reviewer's nod alone.

@claude

claude Bot commented Aug 5, 2026

Copy link
Copy Markdown

Claude is reviewing PR #204

Tasks

  • Gather context (PR body, diff, prior review, author's response comment)
  • Re-check the diff since the prior review (commits 70a1f1a2, bc3b64b2)
  • Verify the author's claims in their "Review response" comment (manifest fix, check-review-posted.sh pipe/EPIPE theory)
  • Run relevant tests
  • Post final review

View job run

The ledger already warns that a GREEN review check can mean the reviewer never
ran. The inverse also holds and cost this PR a full diagnosis pass, so it is
worth writing down rather than rediscovering.

check-review-posted.sh pipes comment bodies into `grep -q` under pipefail.
`grep -q` exits on first match, `printf` takes EPIPE on the remainder, and
pipefail turns that into the pipeline's status - so locating the review early is
precisely what makes the gate report "no review posted". Deterministic at the
64 KiB pipe buffer: measured on this PR at 65536 bytes -> PASS, 70000 -> FAIL,
with the run id present and correctly cited throughout.

The failure mode is backwards - it fires when the reviewer works and the PR is
busy - and worsens as comment payloads grow. The error text also blames the
workflow-validation guard, which sends the reader after a .github/ diff that is
not there.

Not fixing the gate here: a CI gate patched by the PR it is blocking certifies
nothing. Recorded so it can be fixed on its own.
@claude

claude Bot commented Aug 5, 2026

Copy link
Copy Markdown

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


Code review

  • Gather context (PR body, prior automated review, author's review-response comment, diff)
  • Re-read the three changed source files and both new test classes
  • Independently verify both regression claims by reverting each fix and re-running the test (not just trusting the PR body)
  • Check the follow-up commits (manifest fix, ci-review-agent.md note) added since the last review
  • Run the copyright header check
  • Post review

Summary

I re-verified this independently rather than re-reading the prior review's conclusions. Both central regression claims check out:

  • Reverted commitOffsetsReportingPollerDeath()commitOffsetsThatAreReady() at AbstractParallelEoSStreamProcessor.java:890, recompiled, ran CommitResponseTimeoutSymptomTest. aDeadPollThreadReportsItsOwnCauseNotTheCommitResponseTimeout goes red exactly as described — anyMatch(... AuthorizationException) fails, the real cause is absent from the chain. Restored the source (git diff against the PR branch is now empty for that file) and reran: both tests green in 3.3s.
  • Reverted the startedTime hoist in ConsumerManager.commitSync back inside the retry loop, recompiled, ran ConsumerManagerCommitRetryBudgetTest. Fails red — the log shows 51 attempts against the 500ms budget before the mock relents, matching the PR's own measurement exactly, and the test's assertThrows fails because nothing was thrown. Restored the source and reran: green.
  • bin/check-copyright-headers.sh — clean, 0 violations.

I also checked controlLoop() directly (AbstractParallelEoSStreamProcessor.java:877-926): the pre-existing brokerPollSubsystem.supervise() call at line 911 really is unreachable in the hang scenario, since commitOffsetsReportingPollerDeath() at line 890 blocks for the full offsetCommitTimeout and then throws before execution ever reaches line 911. That supports the javadoc's claim that supervising earlier in the loop doesn't help.

On the follow-up commits (review response)

  • 70a1f1a2: bug-833-commit-response-timeout in upstream-map.yaml now reads prs: [204] / status: pr-open — confirmed correct against AGENTS.md's upstream-tracking rule, and consistent with the rest of the manifest's schema.
  • 572ef3a8: the check-review-posted.sh EPIPE explanation in docs/inflight/ci-review-agent.md is mechanically sound (grep -q short-circuiting causes printf's builtin write to fail with EPIPE, which pipefail then propagates) — a well-known bash gotcha, correctly diagnosed. I didn't reproduce the exact byte-count thresholds in this sandbox (no python3/general shell scripting permitted here), but the reasoning holds up on inspection and doesn't touch shipped code, so it's low-risk regardless.
  • Both are docs-only, no functional risk.

On the flagged ConsumerManager.commitSync behaviour change

The author explicitly asked for a maintainer call on whether this should ride along with the diagnostics fix or be split out/opt-in. My take: keep it as-is in this PR. It's not really a new behavior so much as a correction back to what offsetCommitTimeout already documents and promises — the old code silently violated its own contract (infinite retry, no backoff), and poll()'s already-correct identical pattern for the SASL budget shows the divergence was accidental, not intentional. An opt-in flag would mean adding a knob to preserve a bug (unbounded silent retry) that contradicts the option's own name. It's also causally the same failure class as the rest of the PR (broker-down arriving at the identical unhelpful message via a different path), which is a legitimate reason to fix it here rather than split it into an unrelated PR.

Verdict

No correctness issues found, and the two most load-bearing claims in the PR body are now independently confirmed rather than just trusted. Documentation and AGENTS.md conventions are followed correctly, including the fix to the stale manifest entry flagged in the prior review.
(branch: test/177-commit-response-timeout)

…ize-based

The first write-up said the failure was deterministic on total payload size,
measured by truncating this PR's comment list. That was the wrong variable:
truncating from the end also shrinks the bytes AFTER the match, which is what
actually matters. `grep -q` stops at the match, so what decides the outcome is
whether `printf`'s remaining write fits the 64 KiB pipe buffer.

Measured against the gate: 65000 bytes after the match PASSes, 66000 FAILs,
and a 500 KB payload with the match at the end PASSes. This PR demonstrated
both ends - red when the review comment sat 2nd of 5 behind the ~130 KB
similarity report, green on the next run at a LARGER 149 KB total once the
newest review landed at the end with 4 KB behind it.

The practical consequence is worse than "it fails on big PRs": it is positional
and intermittent, so a single green run is not evidence the gate is sound.
@astubbs

astubbs commented Aug 5, 2026

Copy link
Copy Markdown
Owner Author

Correction: my check-review-posted.sh diagnosis had the wrong variable

claude-review went green on this run, and I am not going to let that quietly stand as "the gate is fine" — nor let my earlier claim stand as written, because it was measured wrong.

What I got wrong. I said the failure was deterministic on total payload size, and produced a table by truncating this PR's comment list at increasing byte counts. Truncating from the end also shrinks the bytes after the match, so that experiment moved two variables at once and I attributed the effect to the wrong one.

The actual rule. grep -q stops at the match, so what decides the outcome is whether printf's remaining write fits the 64 KiB pipe buffer. Bytes before the match are irrelevant. Measured against the gate directly:

bytes after the match gate
65000 PASS
66000 FAIL
200000 FAIL
500 KB payload, match at the end PASS

This PR demonstrated both ends, which is the useful part. It failed at 137 KB total with the reviewer's comment 2nd of 5 and the ~130 KB file-similarity report behind it. It passed on the very next run at a larger 149 KB total — because the newest review comment was appended at the end, leaving only 4142 bytes after the match:

total bytes = 149502
first match byte offset = 145360
bytes remaining after match = 4142   -> under 64 KiB -> PASS

Why this matters more than the original claim. The bug is positional and intermittent, not size-monotonic. It fires whenever a review lands early in a comment list with bulky bot reports behind it — which is the normal shape whenever the reviewer edits its comment in place rather than appending a new one. So:

  • A green claude-review is not evidence the gate is sound. This PR went red then green with the review correct and correctly cited both times; nothing about the reviewer changed.
  • Re-running a red claude-review can flip it green for reasons unrelated to the review, which is the worst property a gate can have — it trains people to hit retry.

Corrected in docs/inflight/ci-review-agent.md in 9cb5e58. The fix is still the one-liner (grep -qE … <<<"$comment_bodies", no pipe, no EPIPE), and still belongs in its own PR — I have not touched the gate here.


Everything else from my previous comment stands: the manifest entry is fixed (70a1f1a), and the two duplication findings are import preambles and a package-floor identifier overlap respectively, which I am not refactoring.

On the ConsumerManager.commitSync behaviour change — the second review's recommendation is to keep it in this PR, on the grounds that it restores what offsetCommitTimeout already documents rather than introducing new behaviour, and that an opt-in flag would mean adding a knob to preserve a bug. I think that reasoning is right, but it is still a maintainer call, not a reviewer one, and I have flagged it rather than treating the review as sign-off. The cost stands as stated: a broker outage longer than offsetCommitTimeout where a later attempt would have succeeded now shuts PC down instead of retrying forever.

@claude

claude Bot commented Aug 5, 2026

Copy link
Copy Markdown

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


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


Code review

Tasks

  • Gather context (PR body, prior reviews, author's review-response comments)
  • Re-check the diff since the last full review — only one new commit landed (9cb5e589, docs-only)
  • Independently re-verify both regression claims by reverting each fix and re-running the discriminating test
  • Verify the manifest fix, doc corrections, and copyright headers
  • Post final review

What changed since the last review

Only 9cb5e589 — docs-only, in docs/inflight/ci-review-agent.md. It corrects the earlier check-review-posted.sh write-up: the original claim was that the gate fails based on total comment-payload size; the correction is that it's the bytes after the match that matter (grep -q short-circuits, so only printf's unwritten remainder can EPIPE past the 64 KiB pipe buffer). I read bin/check-review-posted.sh:56,94 directly — set -euo pipefail and printf '%s\n' "$comment_bodies" | grep -qE … are exactly as described, so the mechanism is sound. This doc-only correction carries no functional risk.

Independent verification (not re-trusting the prior passes)

I reverted each fix in the working tree, rebuilt, and ran the discriminating test — then restored and re-ran to confirm green:

  • commitOffsetsReportingPollerDeath()commitOffsetsThatAreReady() at AbstractParallelEoSStreamProcessor.java:890: CommitResponseTimeoutSymptomTest#aDeadPollThreadReportsItsOwnCauseNotTheCommitResponseTimeout goes redanyMatch(...) on the exception chain for AuthorizationException fails, exactly as claimed. Restored → green.
  • ConsumerManager.commitSync's startedTime hoist: my first revert attempt (moving it just outside the inner retry loop) didn't actually reproduce the bug — it still passed, which is itself a useful confirmation that the scope of the fix matters, not just "outside the outer loop." Moving Instant startedTime = Instant.now() truly inside the inner while (tryCount == 0 || …) loop reproduced it: ConsumerManagerCommitRetryBudgetTest fails at exactly 51 attempts against the 500ms budget without ever throwing — matching the PR's own measurement to the attempt. Restored → green, working tree confirmed clean (git diff --stat empty) afterward.
  • bin/check-copyright-headers.sh → clean, 0 violations.
  • src/docs/development/upstream-map.yaml's bug-833-commit-response-timeout entry → confirmed prs: [204] / status: pr-open, matching the fix claimed in 70a1f1a2.

Assessment

Both load-bearing regression claims hold up under independent reversion, not just re-reading the prior reviews' conclusions. The three source fixes (AbstractParallelEoSStreamProcessor, ConsumerManager, ConsumerOffsetCommitter) match their PR-body descriptions exactly, the manifest and docs housekeeping is correct, and the only change since the last full pass is a docs-only correction that is itself accurate against the actual script. No correctness issues found.

On the flagged ConsumerManager.commitSync behaviour change (author asked for a maintainer call, not a reviewer one): no new information changes the prior assessment — it restores what offsetCommitTimeout already documents rather than introducing new behavior, and poll()'s already-correct identical pattern for the SASL budget is good evidence the original placement was accidental. That remains a maintainer decision to ratify, not a review blocker.

@astubbs

astubbs commented Aug 5, 2026

Copy link
Copy Markdown
Owner Author

Scope note for whoever picks this up

This PR deliberately does not close #177, and there is no closing link in the description. On merge, #177 stays open. Intentional, and the reasoning matters more here than on the sibling PRs.

Done here: the reader-facing half. The error now names the real failing subsystem instead of Timeout waiting for commit response PT30S, and the message no longer interpolates the constant DEFAULT_TIMEOUT - it previously always printed PT30S regardless of configuration, overstating the 10s default threefold, which is why the original report's number was meaningless.

Not done, and it is a class rather than a bug: the broker-poll thread is the only producer of commit responses, so any exception that kills it turns every later sync commit into the same message. #100/#108 removed two such exceptions. Broker-down, offset-encoding and authorization failures still produce it. Fixing exceptions one at a time never closes this - it wants a supervision change, which is out of scope here.

Two things needing a maintainer decision before merge, not a reviewer's:

  1. ConsumerManager.commitSync behaviour change. The retry budget was captured inside the retry loop, so every attempt reset it - measured at 51 attempts against a 500ms budget. It now honours offsetCommitTimeout as the code's own comment always claimed. This does not make PC keep running where it previously shut down; the reverse - the shutdown path was previously unreachable and PC became a zombie with the poll thread spinning. The honest cost: a broker outage longer than offsetCommitTimeout, where a later attempt would have succeeded, now shuts PC down instead of retrying indefinitely. The reviewer endorsed keeping it here (an opt-in flag would mean adding a knob to preserve a bug), but a reviewer's nod is not the maintainer's sign-off.
  2. Whether confluentinc#833: ParallelConsumer would run for a while and then exit due to InternalRuntimeException(Timeout) #177 should be re-scoped to the reporting fix and closed, with a new issue opened for the poll-thread supervision class. Otherwise that class is tracked only inside this PR body.

astubbs added a commit that referenced this pull request Aug 6, 2026
check-review-posted.sh:94 ran `printf | grep -q` under `set -o pipefail`. grep
exits the instant it matches, printf then dies with EPIPE (141), and pipefail
promotes that to the pipeline's status - so a comment citing the run made the
check fail. It only bites when more than one pipe buffer (64 KiB) of comment
data follows the match, which is why it looked intermittent.

Observed on #198, #199, #204 and #210. On #210 the review comment sat 4.7 KB
into the stream with a 127 KB similarity report behind it; the job log carries
`printf: write error: Broken pipe` directly above the failure. The emitted error
blamed the workflow-validation guard, which none of those PRs had tripped.

The fix is the herestring this repo already prescribes: the same bug class is
guarded against in bin/test-check-copyright-headers.sh, whose comment records it
"seen live in CI". check-review-posted.sh shipped in that same commit without
the guard.

Two tests, both verified to fail against the old line:
- functional: match found, then >64 KiB of further comments. The existing cases
  dance around this - case 5 buries the match but keeps it small, case 6 puts it
  last so nothing follows to fill the buffer.
- structural: the checker may not pipe into grep -q or awk at all, mirroring the
  copyright scanner's guard, so the next instance of the class is caught rather
  than the next occurrence of this one.

The error text is left alone: it misdiagnosed those four PRs only because of this
bug, and becomes accurate again once the SIGPIPE path is gone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtNUsxokE9g2pSEjBHZqNA
astubbs added a commit that referenced this pull request Aug 6, 2026
#211 added a rule to bin/AGENTS.md - never pipe into `grep -q` under pipefail -
while the repo broke it in four places. A rule shipped with known violations is
not a rule.

`writer | grep -q PATTERN` under `set -o pipefail` reports failure exactly when
it MATCHES: grep exits on the first hit, the writer takes EPIPE (141), pipefail
promotes that to the pipeline's status. It only fires once the writer still has
more than one pipe buffer (64 KiB) to write, so it passes every small fixture
and surfaces when real data grows.

- check-review-posted.sh:94 - live. Reported "no review posted" on four PRs
  whose reviews had posted (#198, #199, #204, #210).
- check-quarantine-owners.sh:98,110 - latent, and close. `git show` pipes a whole
  source file into `grep -q` inside an `if`. The largest file in the repo is
  65,185 bytes against a 65,536-byte buffer: 351 bytes of headroom, on a file two
  open PRs are adding lines to. It would fail as "annotation missing", not as a
  pipe error.
- quarantine-lane-report.sh:201 - the `||` makes a SIGPIPE take the wrong branch
  and silently retarget, rather than shielding it.

All four become herestrings, which have no pipeline to fail.

Adds bin/check-shell-sigpipe.sh, run in CI beside the copyright self-test
(seconds, no JDK) and granted to the reviewer. Verified both directions: clean on
this tree, exit 1 when the old line is reinstated. It skips itself, since its
failure message necessarily contains the anti-pattern as the "wrong" half of a
worked example.

shellcheck does NOT detect this - run against the known-bad line, it passed
clean. Hence a bespoke grep rather than adopting a linter.

Note check-review-posted.sh:94 is also fixed in #210, which adds the functional
regression test for it. Conflict expected and cheap; this PR fixes it because it
is this PR that states the rule.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtNUsxokE9g2pSEjBHZqNA
astubbs added a commit that referenced this pull request Aug 6, 2026
`writer | grep -q` under `set -o pipefail` reports failure exactly when it
MATCHES: grep exits on the first hit, the writer takes EPIPE (141), pipefail
promotes that to the pipeline's status. It only fires once the writer still has
more than one pipe buffer (64 KiB) to write, so it passes every small fixture
and surfaces when real data grows.

- check-review-posted.sh:94 - live. Reported "no review posted" on four PRs
  whose reviews had posted (#198, #199, #204, #210).
- check-quarantine-owners.sh:98,110 - latent, and close. `git show` pipes a whole
  source file into `grep -q` inside an `if`. The largest file in the repo is
  65,185 bytes against a 65,536-byte buffer: 351 bytes of headroom, on a file two
  open PRs are adding lines to. It would fail as "annotation missing", not as a
  pipe error, sending the reader nowhere near the cause.
- quarantine-lane-report.sh:201 - the `||` makes a SIGPIPE take the wrong branch
  and silently retarget, rather than shielding it.

All four become herestrings, which have no pipeline to fail.

Kept separate from the guard that enforces this, so the fixes can be reviewed -
and reverted - on their own.

shellcheck does NOT detect this: run against the known-bad line, it passed clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtNUsxokE9g2pSEjBHZqNA
astubbs added a commit that referenced this pull request Aug 6, 2026
`writer | grep -q` under `set -o pipefail` reports failure exactly when it
MATCHES: grep exits on the first hit, the writer takes EPIPE (141), pipefail
promotes that to the pipeline's status. It only fires once the writer still has
more than one pipe buffer (64 KiB) to write, so it passes every small fixture
and surfaces when real data grows.

- check-review-posted.sh:94 - live. Reported "no review posted" on four PRs
  whose reviews had posted (#198, #199, #204, #210).
- check-quarantine-owners.sh:98,110 - latent, and close. `git show` pipes a whole
  source file into `grep -q` inside an `if`. The largest file in the repo is
  65,185 bytes against a 65,536-byte buffer: 351 bytes of headroom, on a file two
  open PRs are adding lines to. It would fail as "annotation missing", not as a
  pipe error, sending the reader nowhere near the cause.
- quarantine-lane-report.sh:201 - the `||` makes a SIGPIPE take the wrong branch
  and silently retarget, rather than shielding it.

All four become herestrings, which have no pipeline to fail.

Kept separate from the guard that enforces this, so the fixes can be reviewed -
and reverted - on their own.

shellcheck does NOT detect this: run against the known-bad line, it passed clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtNUsxokE9g2pSEjBHZqNA
astubbs added 3 commits August 6, 2026 15:29
…changed

Merging master brought three things that bear on this branch.

The issue-reference gate (735b1d3) flags a bare `#NN` below #1000 on added
lines, because the fork's numbers sit entirely inside confluentinc's range. This
branch added 12 such refs across javadoc, tests and the inflight note. Now
owner-qualified: #177/#100/#108/#186/#204 for the fork, confluentinc#833
for upstream. #177 is itself the mirror of confluentinc#833, so the pair
reads correctly. Left `// fixes github issue confluentinc#809` alone - it is a pre-existing
line, not one this PR adds, and rewriting it would be scope creep.

The SIGPIPE gate bug this PR diagnosed is FIXED on master (cb8b118) and guarded
repo-wide (7586b8c), so the inflight entry claiming it still needs its own PR
was stale. Rewritten as resolved, keeping the measurements and the lesson: the
failure is positional rather than size-monotonic, shellcheck does not catch it,
and small fixtures never reproduce it.

The manifest lost the backlink tooling and the `todo` subcommand, so this entry's
`forwarded:` block and `todo:` list were writing into fields nothing reads any
more. Dropped both; the release-time note moved into `notes:`, and `fork_issue:
177` added to match the shape master's entries now use.

Worth recording: cb8b118 called out check-quarantine-owners.sh as latent with
351 bytes of headroom "on a file two open PRs are adding lines to". This is one
of those PRs, and it takes AbstractParallelEoSStreamProcessor.java to 67,168
bytes - 1,632 past the 64 KiB buffer. Without that fix this branch would have
failed as "annotation missing".
Applies 16ac63b's rule to this branch's new test. The rule landed after these
tests were written: await the value you are about to assert, never a proxy that
leads it.

CommitResponseTimeoutSymptomTest had one real instance. It awaited a Set
populated INSIDE the user function, then read commitsRejected, which the
broker-poll thread increments inside commitSync. Two threads, neither ordering
the other. The margin is genuinely large - feeding spans tens of commit
intervals - which is what every latent race looks like right up until it loses.
Now awaited on the value actually asserted, which masks nothing: if the
rejections never arrive it still fails.

The other await-then-assert in the same class is the SAFE direction and is now
commented as such, because the next reader applying this rule would otherwise
"fix" it into a weaker test. supervisorLoop() assigns failureReason BEFORE
doClose() sets state=CLOSED and before the throw that completes
controlThreadFuture, and isClosedOrFailed() reads only those two later signals -
so the awaited signal lags the asserted value. Awaiting a non-null
getFailureCause() instead would hide exactly the regression this test exists to
catch, since a null cause is that regression's signature.

Recorded as a third instance on the existing write-up rather than a new file.
Its value is that one class now holds one site of each direction, so the
refined rule is concrete: establish which value is WRITTEN first. If the awaited
signal is written after the asserted one, the await is sound and tightening it
weakens the test.

Discriminating power is unchanged - the first await (succeeded.hasSize(KEYS)) is
untouched and still runs first.
@astubbs

astubbs commented Aug 6, 2026

Copy link
Copy Markdown
Owner Author

Updated from master

Merged origin/master cleanly — no conflicts. Three of the new commits bore on this branch, and two required changes.

1. Issue-reference gate — 12 refs qualified

735b1d3a (#114) added a PR Checklist step that fails a bare #NN below 1000 on added lines. This branch had 12, across javadoc in all three changed source files, both new tests, and the inflight note. Now owner-qualified: astubbs#177/#100/#108/#186/#204 for the fork, confluentinc#833 for upstream. Gate replayed locally against the real diff: 0 hits.

Two judgement calls worth flagging:

  • // fixes github issue #809 was left alone. My first pass rewrote it, then I checked and it is a pre-existing line on master, not one this PR adds. The gate only inspects added lines, and rewriting untouched code would be scope creep. Reverted.
  • astubbs#177 turns out to be the fork mirror of confluentinc#833, so citing both is not redundant — it gives a reader a clickable fork-local number and the original.

The PR body is qualified too, using the fully-qualified confluentinc/parallel-consumer#833 form AGENTS.md requires for anything posted to GitHub, since a bare #NN in a comment resolves against whichever repo it is posted in.

2. The SIGPIPE bug diagnosed on this PR is fixed on master

cb8b1182 fixed it with the herestring, and 7586b8c7 now guards the whole class. So the red claude-review this PR spent a pass diagnosing is gone at the root, and I have rewritten docs/inflight/ci-review-agent.md from "needs its own PR" to resolved — keeping the measurements and the durable lesson (writer | grep -q under pipefail inverts its own answer; shellcheck does not catch it; small fixtures never reproduce it).

One thing worth putting on the record. cb8b1182 called check-quarantine-owners.sh latent with "351 bytes of headroom … on a file two open PRs are adding lines to". This is one of those two PRs, and it takes AbstractParallelEoSStreamProcessor.java to 67,168 bytes — 1,632 past the 64 KiB buffer. Without that fix, this branch would have gone red as "annotation missing", which points nowhere near the cause. The prediction was exactly right, and this PR is what would have proved it.

3. 16ac63b1 applies here, and found one real site

Await the value you are about to assert, never a proxy that leads it. I checked both await-then-assert sites rather than assuming, and they turned out to be one of each direction — which is the useful part, so it is recorded as a third instance on the existing write-up rather than a new file.

Genuine instance, fixed. The test awaited a Set populated inside the user function, then read commitsRejected, incremented on the broker-poll thread inside commitSync. Two threads, neither ordering the other:

await().untilAsserted(() -> assertThat(succeeded).hasSize(KEYS));  // user-function thread
assertThat(commitsRejected.get()).isAtLeast(MIN_REJECTIONS);       // broker-poll thread

The margin is large — feeding spans tens of commit intervals — but that is what a latent race looks like until it loses. Now awaited on the value actually asserted. Nothing is masked: if the rejections never arrive, it still fails. Discriminating power is unchanged, because succeeded.hasSize(KEYS) is untouched and still runs first.

Already the safe direction, and deliberately kept. Awaiting isClosedOrFailed() then asserting getFailureCause() is sound: supervisorLoop() assigns failureReason before doClose() sets state=CLOSED and before the throw that completes controlThreadFuture, and isClosedOrFailed() reads only those two later signals — so the awaited signal lags the asserted value. The volatile read in FutureTask.isDone() also supplies the happens-before edge. Converting this to "await a non-null cause" would be a real loss of test strength, since a null cause is precisely that regression's signature. Commented at the site so the next person applying the rule does not weaken it.

Refined rule added to the write-up: establish which of the two values is written first. If the awaited signal is written after the asserted one, the await is sound and tightening it weakens the test.

Not changed

810283c0 (self-hosted lanes), 67f6f3df (TODO index — bin/todo-index.sh --check reports up to date), and c6fff838 (merge-strategy guidance) need nothing here.

Verified locally on the merged tree: both new test classes green, check-copyright-headers.sh clean (234 files, 0 violations), check-shell-sigpipe.sh and check-action-versions.sh both ok, upstream-map.py validate OK.


Still needs your call, unchanged by the merge

The ConsumerManager.commitSync retry-budget change has not been signed off. Restating the cost plainly, as it still stands in the PR body:

A broker outage longer than offsetCommitTimeout, where a later attempt would have succeeded, now shuts PC down instead of retrying indefinitely.

The reviewer recommended keeping it in this PR; that is a reviewer's opinion, not sign-off. If you want it split out or made opt-in, say so and I will do that.

Merge-strategy recommendation (per c6fff838)

Now required before merge, so: squash is wrong here, and rebase-as-is is wrong too — I recommend re-cutting into three atomic commits. The branch holds genuinely separate workstreams that someone would want to bisect or revert independently:

  1. The diagnostics fix — poller supervision on the commit-failure path, plus the corrected timeout in the message. Self-contained and uncontroversial.
  2. The commitSync retry-budget fix — the behaviour change. It must stay its own commit precisely because it is the one you might later want to revert alone, and squashing would weld it to the diagnostics fix permanently.
  3. The test/docs resync — reference qualification, the 16ac63b1 await fix, and the ledger/manifest updates.

The review-response and correction commits are noise and should be folded in. If you would rather not re-cut, squash — but then the behaviour change loses its own revert point, which I would not choose.

@claude

claude Bot commented Aug 6, 2026

Copy link
Copy Markdown

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


Code review

Tasks

  • Gather context (PR body, prior reviews, author's comments, diff)
  • Re-check the diff since the last full review — only one substantive new commit landed (cedd1715), plus a docs-only reference-qualification commit (5cbf1450) and a no-op-here merge (dd30eef7)
  • Verify the cedd1715 claims against the actual source (ordering of failureReason vs. state=CLOSED vs. controlThreadFuture completion)
  • Run the affected test class directly
  • Post final review

What changed since the last full review

Since the previous pass (which covered through 9cb5e589), three commits landed:

  • c6fff838 / dd30eef7 — unrelated master-merge content (merge-strategy doc guidance), no functional change to this branch's diff.
  • 5cbf1450 — docs-only: qualifies the 12 bare #NN issue references flagged by the reference gate, and syncs the upstream-map.yaml/ci-review-agent.md prose to what actually shipped on master. Nothing here touches test or production logic.
  • cedd1715 — the one commit worth reviewing on its merits: applies the "await the value you assert, never a proxy that leads it" rule to CommitResponseTimeoutSymptomTest, and documents the third instance in the existing write-up.

Verification of cedd1715

I checked the ordering claim directly against AbstractParallelEoSStreamProcessor.java rather than trusting the commit message:

  • failureReason is assigned at line 855, before doClose(shutdownTimeout) is called at line 856, which sets state = CLOSED at line 667, and before the throw failureReason at line 857 that completes controlThreadFuture.
  • isClosedOrFailed() (lines 217–225) reads only state == CLOSED and controlThreadFuture.isDone()/isCancelled() — both of which are written after failureReason. So the claim that "the awaited signal lags the asserted value" for the isClosedOrFailed()getFailureCause() site checks out, and leaving that await as-is (rather than "fixing" it to await a non-null cause) is correct — a null cause is exactly the regression signature that would otherwise be hidden.
  • For the other site, commitsRejected really is incremented on the broker-poll thread inside the mocked commitSync, independent of the succeeded set populated on the user-function thread — so the original two-thread race the commit describes is real, and moving to Awaitility.await().untilAsserted(...) on commitsRejected is a legitimate strengthening, not cosmetic. MIN_REJECTIONS = 4 against a 30s timeout is generous relative to the actual measured rejection count (7, in the run below).

Ran the class directly to confirm both tests are still green after this change:

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.378 s -- in io.confluent.parallelconsumer.CommitResponseTimeoutSymptomTest

(aRebalanceStormUnderAHighFailureRateNeitherStallsNorKillsTheConsumer logged "Commit attempts: 21, rejected: 7" in this run, comfortably above MIN_REJECTIONS.)

Minor, non-blocking observation: the code comment's happens-before argument for isClosedOrFailed() leans on FutureTask.isDone() publishing prior writes to an observing thread. That's true for the JDK's actual FutureTask (a volatile state field), but it's an implementation detail rather than something the Future interface formally guarantees outside of get(). Not a real risk in practice — just noting it's leaning on JDK internals rather than the documented contract, for whoever revisits this later.

Verdict

No correctness issues. This increment is docs/test-only, the claimed thread-ordering justification for both directions of the await fix holds up against the actual source, and the affected test class passes. Everything from the prior reviews (the three source fixes, the manifest correction, the check-review-posted.sh diagnosis) stands unchanged since no source files moved in this push.

CI failed it once on this branch with incompletes [8] where the multiple=50
parameter pins [8, 12]. Recorded rather than reacted to, because the test's name
collides with what this PR changes and that invites the wrong conclusion.

It is the family signature: the test's own javadoc names BOTH outcomes as
physically possible - "just the failed offset (processing finishes during
shutdown timeout)" vs "both ... when sleep is longer than the shutdown timeout" -
and the parameter pins one. That encodes a timing outcome as if deterministic.
The ambient probe reached the same verdict unprompted.

Ruled out as a regression from the commitSync retry-budget change on four
independent grounds, the first two of which are decisive on their own:

- Wrong path. This test is PERIODIC_TRANSACTIONAL_PRODUCER, and
  AbstractParallelEoSStreamProcessor picks committer = producerManager for
  transactional mode. ConsumerManager.commitSync has exactly one caller in main,
  ConsumerOffsetCommitter:96, reached only in the consumer-sync modes.
- Wrong direction. The change gives up EARLIER, which leaves MORE incomplete and
  pushes toward [8, 12]. The failure is [8] - fewer - so the effect points away
  from it even if the path were shared.
- Passes locally with the change in place, 3 tests 0 failures.
- The class is already named load-sensitive in two existing write-ups, and its
  sibling produceTimeout is already in the table.

Deliberately not touched: widening the expected set to accept both outcomes
would make the assertion vacuous, since those are the only two possibilities.
@astubbs

astubbs commented Aug 6, 2026

Copy link
Copy Markdown
Owner Author

Integration Tests went red once — diagnosed, not retried away

TransactionTimeoutsTest.commitTimeout[2] failed with incompletes [8] where the multiple=50 parameter pins [8, 12]. I treated this as a possible regression rather than a flake, because the failing test is named commitTimeout and this PR changes commit-timeout behaviour — precisely the coincidence that would make waving it through negligent.

It is not a regression. Four independent grounds, the first two decisive on their own:

1. Wrong code path — the changed method is never called here. The test runs CommitMode.PERIODIC_TRANSACTIONAL_PRODUCER, and AbstractParallelEoSStreamProcessor selects the committer by mode:

if (options.isUsingTransactionalProducer())
    this.committer = this.producerManager.get();
else
    this.committer = this.brokerPollSubsystem;

ConsumerManager.commitSync has exactly one caller in main — ConsumerOffsetCommitter:96 — reached only in the consumer-sync modes. Transactional commits go through ProducerManager.

2. Wrong direction. The change makes commitSync give up earlier. Earlier shutdown leaves more work incomplete — i.e. pushes toward [8, 12]. The observed failure is [8], fewer incompletes. The effect points away from the failure even if the path were shared.

3. Passes locally with the change in placeTransactionTimeoutsTest, 3 tests, 0 failures, 0 errors.

4. Pre-existing member of a documented family. The class is already named as load-sensitive in pc-silent-stall-under-contention-2026-07-29.md and parallel-integration-tests-flaky-under-concurrency-2026-07-28.md, and its sibling produceTimeout is already in the test-load-tightness-flakes.md table.

5. The rerun of the same commit passed — no code changed between the two runs.

Why the test is non-deterministic

Its own javadoc names both outcomes as physically possible — "just the failed offset (for case where processing finishes during shutdown timeout)" versus "both offsetToError and offsetToGoVerySlow ... when sleep is longer than the shutdown timeout" — and the parameterisation pins one. So the assertion encodes a timing outcome as if it were deterministic. That is the family signature: right when quiet, arbitrary under contention. The ambient probe reached the same verdict unprompted:

probe clean - no rebalance dwell, no lag stagnation, no frozen partitions observed: the fault is likely in the test itself, not consumer-group progress

What I did not do

I did not touch the test, widen a timeout, or add a retry. Widening the expected set to accept both outcomes would make the assertion vacuous, since [8] and [8, 12] are the only two possibilities — it would assert nothing. Making it genuinely deterministic means separating the shutdown timeout from the sleep far enough that only one outcome is reachable, or moving it to the quarantine lane. That is someone's deliberate decision, not a drive-by fix inside an unrelated PR, so it is recorded in docs/inflight/test-load-tightness-flakes.md with the ruling-out evidence attached — specifically so the next person who sees commitTimeout fail near this PR does not re-derive it and reach the wrong conclusion.

@claude

claude Bot commented Aug 6, 2026

Copy link
Copy Markdown

Claude Code is working…

I'll analyze this and get back to you.

View job run

@claude

claude Bot commented Aug 6, 2026

Copy link
Copy Markdown

Claude finished @astubbs's task in 1m 47s —— View job


Code review

Tasks

  • Gather context (PR body, prior reviews, latest author comment about TransactionTimeoutsTest.commitTimeout[2])
  • Re-check the diff since the last full review
  • Verify the new commit's claims against actual source
  • Run the copyright header check
  • Post final review

What changed since the last full review

Only one substantive commit landed since the last full review (which covered through cedd1715): b3570b9c, adding a 34-line section to docs/inflight/test-load-tightness-flakes.md. It's a docs-only addition classifying a one-off CI failure of TransactionTimeoutsTest.commitTimeout[2] (incompletes [8] where the multiple=50 parameter pins [8, 12]) as a pre-existing flake, not a regression from this PR's ConsumerManager.commitSync fix. (68651ed4 and the merge commit 54476b33 also appear in the log but only bring in unrelated master content — docs #171 on close() semantics — not part of this PR's own diff.)

I independently verified the classification's claims rather than trusting the write-up:

  • "Wrong code path." Confirmed TransactionTimeoutsTest constructs its consumer with CommitMode.PERIODIC_TRANSACTIONAL_PRODUCER (TransactionTimeoutsTest.java:97-98), and AbstractParallelEoSStreamProcessor selects committer = producerManager.get() when options.isUsingTransactionalProducer(), only falling back to brokerPollSubsystem otherwise. ConsumerManager.commitSync has exactly one caller in main (ConsumerOffsetCommitter.java:96), which is unreachable in transactional mode. The changed method genuinely isn't on this test's path.
  • "Wrong direction." The commitSync retry-budget fix makes the method give up earlier, which should leave more work incomplete (pushing toward [8, 12]), not less. The observed failure ([8]) is the opposite direction from what the change could cause even if it were reachable.
  • Pre-existing membership. Checked both cited sibling docs directly (docs/solutions/test-flakiness/pc-silent-stall-under-contention-2026-07-29.md, docs/solutions/test-flakiness/parallel-integration-tests-flaky-under-concurrency-2026-07-28.md) — both do name TransactionTimeoutsTest as already load-sensitive under contention, so the "pre-existing family member" framing is accurate rather than asserted.

TransactionTimeoutsTest lives under src/test-integration/, needing the Docker-backed integration harness rather than a plain surefire:test run, so I didn't re-execute it myself in this pass — but the reasoning above (path + direction) is independently sufficient to rule out the commitSync change as the cause without needing to reproduce the flake.

  • bin/check-copyright-headers.sh — clean, 234 files, 0 violations.

Verdict

No correctness issues. This increment is docs-only and its reasoning holds up against the actual source (committer selection, single call site, direction of the behaviour change). Combined with the prior rounds' independent verification of the three source fixes (AbstractParallelEoSStreamProcessor, ConsumerManager, ConsumerOffsetCommitter) and the two new test classes, nothing here changes the overall assessment: the diagnosis is sound, the tests are genuinely discriminating, and the one open item remains the same as before — the ConsumerManager.commitSync retry-budget behaviour change is explicitly flagged by the author as needing a maintainer's sign-off, not a reviewer's.

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