Added
- Receive Postgres and SQLite notifications for insertions, queue controls, cancellation, and leadership handoffs, with reconnect recovery and a
poll_onlyoption. PR #1496. - Add
Client#request_resignto request that the maintenance leader relinquish leadership after the caller's transaction commits. PR #1496. - Allow
River::Workers#addto register a kind and a work block, using the client's default retry and timeout policies. PR #1486. - Added
Client#job_complete_tx(job)to complete a running job in the caller's Active Record or Sequel transaction, including pending metadata and output. An active transaction on the driver's connection is required. Completion rolls back with the transaction; once committed, it takes precedence over subsequent worker errors and emits a completion event when the worker finishes. PR #1490.
Changed
- River operations called inside an open Active Record or Sequel transaction now run in that transaction and open no savepoint of their own. If an operation raises, roll back the transaction, or wrap the call in your own savepoint to recover and continue. A
driver.rollback_exceptionraised insideDriver#transactionnow reaches the enclosing transaction block, as a rollback raised in your own code would. Before, it rolled back only River's savepoint. SetRIVER_USE_LEGACY_SUBTRANSACTIONS=1(ortrue) to restore the savepoints. This temporary fallback will be removed in a future release. PR #1544. work_end(job, error)hooks now return the attempt's error, matching Go. Return the incoming error to preserve it, a replacement exception to change it, ornilto clear a failure. The return value feeds the next hook in registration order. Existing observing hooks must explicitly returnerror. End hooks are skipped ifwork_beginraises or the worker raises an exception outsideStandardError. PR #1520.
Fixed
- The scheduler no longer opens a savepoint for each due job to catch unique key conflicts. A pass that made more than 64 jobs available overflowed the Postgres subtransaction cache, which can slow queries across the server. The scheduler now finds conflicts with one statement on Postgres and checks before each write on SQLite. Conflicting jobs are still discarded with
unique_key_conflict: scheduler_discardedmetadata. On Postgres, the scheduler now waits for a due job that another transaction has locked, instead of skipping it. PR #1544. - Default periodic jobs to their occurrence time, preserving constructor and argument-level schedules. PR #1537.
- Fail retries that omit a saved cursor-only step, while preserving their checkpoints for recovery. Jobs with an existing step marker retain their behavior, including legacy stale cursor entries. PR #1534.
- Support large SQLite metadata updates without reaching the expression-depth limit, preserving top-level replacement and JSON null values. PR #1533.
- A
River::Configwithout an explicitid:generates its default client ID on first use in each process, so clients built before a fork (as with preloading Puma, Unicorn, or Pitchfork servers) no longer share one ID across forked workers. Explicit IDs are unchanged, andConfig#withcopies share the original's ID. PR #1498. - Inserting a job stores its encoded args as given instead of decoding and re-encoding them in Ruby, which rewrote numbers like
1.10as1.1and1e3as1000.0and rounded digits beyondFloatprecision. Postgres applies its usualjsonbnormalization, and SQLite keeps the encoded bytes, matching River's Go drivers. Affects Active Record on Postgres and SQLite, and Sequel on SQLite. PR #1503. - Wake workers when scheduled jobs become available or jobs are manually retried, including workers in other clients. PR #1496.
- Honor cancellations that arrive between claiming a job and starting its worker. PR #1496.
- Preserve worker wakeups that arrive between a fetch and the producer going to sleep. PR #1496.