Repository navigation
Conversation
2 tasks
On every push to master, .github/workflows/publish.yml reads the version from pom.xml and either: - Publishes a snapshot (version ends in -SNAPSHOT) - Publishes a release + creates git tag + GitHub release (otherwise) The pom.xml version is the source of truth - no maven-release-plugin dance. To cut a release, merge a PR that strips -SNAPSHOT. Also adds --pinentry-mode loopback to the maven-gpg-plugin so headless CI signing works without a TTY. Documents required GitHub secrets in AGENTS.md and the README dev section: - MAVEN_CENTRAL_USERNAME / MAVEN_CENTRAL_PASSWORD - MAVEN_GPG_PRIVATE_KEY / MAVEN_GPG_PASSPHRASE Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds a separate performance test suite that runs on dedicated hardware via a self-hosted GitHub Actions runner, so the volume tests don't slow down or destabilize regular CI. Test changes: - Tag VeryLargeMessageVolumeTest, LargeVolumeInMemoryTests, and MultiInstanceHighVolumeTest with @tag("performance") - Failsafe now reads excluded.groups (defaults to "performance") and included.groups (defaults to empty), so the performance group is excluded by default. Override with -Dincluded.groups=performance to run only perf, or -Dexcluded.groups= to run everything. Scripts: - bin/performance-test.sh and bin/performance-test.cmd run the perf suite locally (.cmd for Windows since the runner is on Windows) Workflow: - .github/workflows/performance.yml targets a self-hosted runner labelled [self-hosted, windows, performance] - Triggers: workflow_dispatch (manual) + weekly schedule - Never runs on PRs (security: self-hosted + untrusted code = bad) Documentation: - docs/SELF_HOSTED_RUNNER.md walks through one-time runner setup on Windows with Docker Desktop and the WSL2 backend - README template and AGENTS.md mention the performance suite and link to the runner setup doc - Fix a stale link in README to the renamed VolumeTests file Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a "License headers" section to AGENTS.md explaining how to skip the Mycila license-maven-plugin check. This avoids two recurring problems: - The plugin's git-derived copyright years break inside git worktrees - It auto-bumps years on every touched file, creating noise in git status that distracts from real changes The bin/build.sh and bin/ci-build.sh scripts already pass the flag. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
astubbs
force-pushed
the
dev/self-hosted-runner
branch
from
April 20, 2026 22:49
848ddbc to
faa3adb
Compare
astubbs
force-pushed
the
dev/maven-publish
branch
from
April 20, 2026 22:52
230e5d9 to
a66b635
Compare
Owner
Author
|
Closed during the April 2026 rebrand/CI restructure. The branch |
astubbs
added a commit
that referenced
this pull request
Sep 2, 2026
…rupt as a wake-up, and end recovery on the failures retrying cannot fix Recovery lifecycle findings #3, #4, #8, #13, #17, #22, #23 and #27 of the #410 review, each with a test that was red against the previous code (run as a mutant of this commit - the old behaviour reinstated line by line - and green after). What changed for a user of the PC-built transactional path: - A replacement producer that was built but failed initTransactions is now closed before the retry is scheduled. It was leaked: nothing held a reference to it, and each one kept a KafkaProducer network thread - about 120 per hour at the 30 s backoff cap while a coordinator was unreachable. Both catch branches close it (ProducerManagerRecoveryTest: aReplacementThatFailsToInitialiseIsClosedBeforeTheRetryIsScheduled, aReplacementThatFailsTerminallyIsClosedToo). - The recovery counter and its log line moved out of the build try. The counter is the user's MeterRegistry, which has thrown from inside PC before (docs/solutions/runtime-errors/a-throwing-meter-registry-kills-the- poll-thread-and-strands-close.md); a throw there turned a published, in-use replacement into a DEFERRED outcome that scheduled a second rebuild against it (aThrowingMeterRegistryDoesNotTurnACompleted ReplacementIntoADeferredOne). - An interrupt while recovery waits for the producer write lock no longer closes the instance. notifySomethingToDo interrupts the control thread whenever the write lock is not HELD, and it is not held while WAITING for it - which recovery does for as long as a worker holds the produce lock through its user function; the rebalance that fenced the producer ends with onPartitionsAssigned, which notifies. The InterruptedException escaped maybeRecoverProducer's RuntimeException catch and the supervisor closed PC with no failure cause. It is now caught, cleared and the pass returns; the condition stays recorded and the next pass retries, the same shape as the mailbox poll's own catch. maybeRecoverProducer no longer declares InterruptedException, so the compiler holds the line (ProducerRecoveryTest: aWakeUpInterruptWhileRecoveryWaitsForTheWriteLock DoesNotCloseTheInstance - one record only, so the commit path's separate, pre-existing exposure to the same interrupt does not take it first). - An Error from the user's ProducerFactory is terminal. The factory is user code and is now wrapped by UserFunctions.carefullyRun like every other user function; an Error in the cause chain (a serializer's static initialiser failing, say) is deterministic and joins AuthorizationException and UnsupportedVersionException as a terminal build failure, so the instance closes naming the type, and its parked workers are released by the close. Before, the Error escaped every catch on the recovery path: the supervisor's catch is Exception, so the instance stayed RUNNING with every worker parked on the produce lock for good. maybeRecoverProducer also catches Error from anywhere else in the pass, records it as the failure reason and transitions to CLOSING before rethrowing, for the same release (anErrorFromTheFactoryIsTerminalAndClosesTheInstanceNamingIt). - A factory contract violation is terminal, not deferred. Returning null, returning the producer it already returned, or building a producer that does not carry the transactional.id PC handed it now raise ProducerFactoryContractException, a dedicated type the terminal predicate recognises. Every one is deterministic - a caching factory caches on every rebuild, never only the first - so retrying was a WARN-per-attempt loop for the life of the instance (aFactoryContractViolationIsTerminalRather ThanRetriedForever). - Recovery is skipped once the instance is CLOSING or CLOSED. A close during an outage otherwise waited on a rebuild that blocks up to max.block.ms for a producer nobody would use; ProducerManager.close releases the parked workers on its own. DRAINING still recovers, because a drain needs a producer to finish the work in flight (noReplacementIsAttemptedOnceThe InstanceIsClosing, driven directly - the window is the control thread's). Smaller: the two raw producerWrapper call sites the field javadoc claimed did not exist (sendOffsetsToTransaction and beginTransaction) go through producer(), and the javadoc now says exactly which paths read the field raw (the constructor and initProducer, before any replacement can exist); restoreWorkDiscardedByAbortedTransaction's count is named at its call site per the house rule; the pollAndProduceMany guard names producerConfig first and the Producer instance as deprecated. The terminal failure names the root cause's type as well as the wrapper's - types only, never messages, which may carry configuration values (R7). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VrpH51xNDodaajE4P2nhFg
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Splits the volume tests into a separate "performance" test group that runs on a self-hosted GitHub Actions runner (Windows + Docker Desktop), so they don't slow down or destabilize the regular CI.
Test changes
@Tag("performance"):Workflow
`.github/workflows/performance.yml`:
Scripts
Documentation
What you need to do once after merging
Stacked on
This PR is stacked on top of #26 (dev/maven-publish), which is itself stacked on #25 and #24.
🤖 Generated with Claude Code