Repository navigation
[java] Move worker lifecycle to Client and RunHandle - #1555
Merged
Merged
Conversation
Put runtime configuration and startup on Client, consistent with the
other River clients. Workers becomes a registry of typed handlers, while
Client.start() returns an AutoCloseable RunHandle for one execution.
Shutdown and runtime queue/periodic controls belong to that handle.
For example:
var workers = new Workers().add(email, context -> sendEmail(context.args()));
var client = Client.builder(database)
.queue("default", 10)
.workers(workers)
.build();
try (var run = client.start()) {
application.awaitStop();
}
RunHandle.stop() and close() drain active attempts; stopAndCancel() also
requests cancellation. A client permits only one active run, including
while a timed-out stop drains. Successful shutdown allows restart with
the same client ID, and stopping an old handle cannot affect a later run.
Insert-only clients still need no lifecycle calls, and the application
continues to own its database pool.
Move subscriptions and event types to Client so callers can subscribe
before startup without missing immediately completed jobs. Subscriptions
remain registered across restarts until closed. Registries and builders
are snapshotted, and each restart restores configured queues and periodic
jobs rather than carrying over changes made to the previous run.
Update the conformance adapter, examples, API inventory, and changelog,
including a migration guide from 0.1.0. Add regression coverage for
concurrent starts, startup failure recovery, registry snapshots, local
insert wakeups, subscriptions, restarts, and both stop modes.
Validation:
- make lint/java test/java/tools test/java/sqlite check/java/package
- make test/java/postgres against a disposable local database
- Compile and run the README quick start against SQLite
- Exercise the conformance adapter with pre-start jobs, completion
events, and two start/stop cycles
- Java CI on Java 21/25 and Postgres 14-18
A built client stores its effective rescueAfter value, including the
default derived from jobTimeout. Copying that value through toBuilder()
treated it as an explicit override, so increasing the job timeout could
incorrectly fail validation. For example, copying a default client and
setting a two-hour timeout retained the one-hour rescue delay:
client.toBuilder().jobTimeout(Duration.ofHours(2)).build();
Track whether rescueAfter was explicitly configured. Recompute an
implicit delay when building the copied configuration; the example now
gets the expected three-hour delay. Preserve explicit overrides and
continue rejecting values shorter than the job timeout.
Add a regression test covering both implicit and explicit rescue delays.
Validated with make lint/java, all 72 affected lifecycle/runtime/registry
tests on SQLite, and Java CI on Java 21/25 and Postgres 14-18.
brandur
force-pushed
the
brandur-java-client-lifecycle
branch
from
October 27, 2026 03:26
8f797d0 to
1b12141
Compare
Contributor
Author
|
@bgentry Found a piece of the Java API that was weirdly inconsistent here (instead of getting a I'm going to do a quick patch here while we can still break things without much trouble:
|
Link the lifecycle changelog entry to PR #1555. Remove the migration guide for the short-lived previous API; the current API remains documented in the README and API comparison.
Merged
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.
🤖 Move worker configuration and startup onto
Client.Workersnow holds typed handler registrations, andClient.start()returns anAutoCloseableRunHandlewithstop(),stopAndCancel(), and runtime queue/periodic controls.Subscriptions and event types also move to
Client, so callers can subscribe before startup and retain subscriptions across restarts. A client permits only one active run, including while a timed-out stop drains. Successful shutdown allows restart with the same client ID; stopping an old handle cannot affect a later run. Insert-only clients still need no lifecycle calls.Update the existing runtime tests, conformance adapter, examples, API inventory, and changelog. Add regression coverage for concurrent starts, startup failure recovery, registry snapshots, local insert wakeups, subscriptions, restarts, and both stop modes.
Validation:
make lint/java test/java/tools test/java/sqlite check/java/packagemake test/java/postgresagainst a disposable local database