Releases: riverqueue/river
v0.23.1
v0.23.0
Terminal UI: @almottier wrote a very cool terminal UI for River featuring real-time job monitoring with automatic refresh, job filtering, a job details view providing detailed information (plus look up by ID in the UI or by command line argument), and job actions like retry and cancellation. And as good as all that might sound, go take a look because it's eve 10000 n better in person.
Added
- Preliminary River driver for SQLite (
riverdriver/riversqlite
). This driver seems to produce good results as judged by the test suite, but so far has minimal real world vetting. Try it and let us know how it works out. PR #870. - CLI
river migrate-get
now takes a--schema
option to inject a custom schema into dumped migrations and schema comments are hidden if--schema
option isn't provided. PR #903. - Added
riverlog.NewMiddlewareCustomContext
that makes the use ofriverlog
job-persisted logging possible with non-slog loggers. PR #919. - Added
RequireInsertedOpts.Schema
, allowing an explicit schema to be set when asserting on job inserts withrivertest
. PR #926. - When using a driver that doesn't support listen/notify, producers within same process are notified immediately of new job inserts and queue changes (e.g. pause/resume) without having to poll when non-transactional variants are used (i.e.
Insert
instead ofInsertTx
). PR #928. - Added
JobListParams.Where
, which provides an escape hatch for job listing that runs arbitrary SQL with named parameters. PR #933.
Changed
- Optimized the job completer's query
JobSetStateIfRunningMany
, resulting in an approximately 15% reduction in its duration when completing 2000 jobs, and around a 15-20% increase inriverbench
throughput. PR #904. TimeStub
has been removed from therivertest
package. Its original inclusion was entirely accidentally and it should be considered entirely an internal API. PR #912.- When storing job-persisted logging with
riverlog
, if a work run's logging was completely empty, no metadata value is stored at all (previously, an empty value was stored). PR #919. - Changed the internal integration APIs for River Pro. River Pro users must upgrade both libraries as part of this update. PR #929.
Fixed
- Resuming an already unpaused queue is now fully an no-op, and won't touch the row's
updated_at
like it (unintentionally) did before. PR #870. - Suppress an error log line from the producer that may occur on normal shutdown when operating in poll-only mode. PR #896.
- Added missing help documentation for CLI command
river migrate-list
. PR #903. - Correct handling an explicit schema in the reindexer maintenance service. PR #916.
- Return specific explanatory error when attempting to use
JobListParams.Metadata
withJobListTx
on SQLite. PR #924. - The reindexer now skips work if artifacts from a failed reindex are present under the assumption that if they are, a new reindex build is likely to fail again. Context cancel timeout is increased from 15 seconds to 1 minute, allowing more time for reindexes to finish. Timeout becomes configurable with
Config.ReindexerTimeout
. PR #935. - Accessing
Client.PeriodicJobs()
on an insert-only client now panics with a more helpful explanatory error message rather than an unhelpful nil pointer panic. PR #938. - Return an error when adding a new queue at runtime via the
QueueBundle
if that queue was already added. PR #929.
v0.22.0
Added
- A new
JobArgsWithKindAliases
interface lets job args implementKindAliases
to register a second kind that their worker will respond to. This provides a way to safely rename job kinds even with jobs using the original kind already in the database. PR #880.
Changed
- Job kinds must comply to a format of
\A[\w][\w\-\[\]<>\/.·:+]+\z
, mainly in an attempt to eliminate commas and spaces to make format more predictable for an upcoming search UI. This check can be disabled for now usingConfig.SkipJobKindValidation
, but this option will likely be removed in a future version of River. The newJobArgsWithKindAliases
interface (see above) can be used to rename non-compliant kinds. PR #879.
Fixed
v0.21.0
Added
- Added
river/riverlog
containing middleware that injects a context logger to workers that collates log output and persists it with job metadata. This is paired with a River UI enhancement that shows logs in the UI. PR #844. - Added
JobInsertMiddlewareFunc
andWorkerMiddlewareFunc
to easily implement middleware with a function instead of a struct. PR #844. - Added
Config.Schema
which lets a non-default schema be injected explicitly into a River client that'll be used for all database operations. This may be particularly useful for proxies like PgBouncer that may not respect a schema configured insearch_path
. PR #848. - Added
rivertype.HookWorkEnd
hook interface that runs after a job has been worked. PR #863. - Added support for filtering jobs by a list of job IDs and by priorities in
JobList
andJobListParams
. For more flexible job listing. PR #871.
Changed
- Client no longer returns an error if stopped before startup could complete (previously, it returned the unexported
ErrShutdown
). PR #841.
Fixed
- A queue unpausing triggers an immediate fetch so that available jobs in the paused queue may be started faster than before. PR #854.
v0.20.2
v0.20.1
v0.20.0
Added
- Added a
QueueUpdate
API to theClient
which will be used for upcoming functionality. PR #822.
Changed
- Set minimum Go version to Go 1.23. PR #811.
- Deprecate
river.JobInsertMiddlewareDefaults
andriver.WorkerMiddlewareDefaults
in favor of the more generalriver.MiddlewareDefaults
embeddable struct. The two former structs will be removed in a future version. PR #815.
Fixed
- Cleanly error when attempting to add a queue at runtime to a
Client
which was not configured to run jobs (noWorkers
). PR #826.
v0.19.0
Worker.Middleware
, introduced fairly recently in 0.17.0 that has a worker's Middleware
function now taking a non-generic JobRow
parameter instead of a generic Job[T]
. We tried not to make this change, but found the existing middleware interface insufficient to provide the necessary range of functionality we wanted, and this is a secondary middleware facility that won't be in use for many users, so it seemed worthwhile.
Added
- Added a new "hooks" API for tying into River functionality at various points like job inserts or working. Differs from middleware in that it doesn't go on the stack and can't modify context, but in some cases is able to run at a more granular level (e.g. for each job insert rather than each batch of inserts). PR #789.
river.Config
has a genericMiddleware
setting that can be used as a convenient way to configure middlewares that implement multiple middleware interfaces (e.g.JobInsertMiddleware
andWorkerMiddleware
). Use of this setting is preferred overConfig.JobInsertMiddleware
andConfig.WorkerMiddleware
, which have been deprecated. PR #804.
Changed
- The
river.RecordOutput
function now returns an error if the output is too large. The output is limited to 32MB in size. PR #782. - Breaking change: The
Worker
interface'sMiddleware
function now takes aJobRow
parameter instead of a genericJob[T]
. This was necessary to expand the potential of what middleware can do: by letting the executor extract a middleware stack from a worker before a job is fully unmarshaled, the middleware can also participate in the unmarshaling process. PR #783. JobList
has been reimplemented to use sqlc. PR #795.
v0.18.0
rivertest.Worker
type that was just introduced. While attempting to round out some edge cases with its design, we realized some of them simply couldn't be solved adequately without changing the overall design such that all tested jobs are inserted into the database. Given the short duration since it was released (over a weekend) it's unlikely many users have adopted it and it seemed best to rip off the bandaid to fix it before it gets widely used.
Added
-
Jobs can now store a recorded "output" value, a JSON-encoded payload set by the job during execution and stored in the job's metadata. The
river.RecordOutput
function makes it easy to use the job row to store transient/temporary values that are needed for introspection or for other downstream jobs. The output can be accessed using theJobRow.Output()
helper method.This output is stored at the same time as the job is completed following execution, so it does not require additional database calls or overhead. Output can be anything that can be stored in a Postgres JSONB field, though for performance reasons it should be limited in size. PR #758.
Changed
-
Breaking change: The
rivertest.Worker
type now requires all jobs to be inserted into the database. The original design allowed workers to be tested without hitting the database at all. Ultimately this design made it hard to correctly simulate features likeJobCompleteTx
and the other potential solutions seemed undesirable.As part of this change, the
Work
andWorkJob
methods now take a transaction argument. The expectation is that a transaction will be opened by the caller and rolled back after test completion. Additionally, the return signature was changed to return aWorkResult
struct alongside the error. The struct includes the post-execution job row as well as the event kind that occurred, making it easy to inspect the job's state after execution.Finally, the implementation was refactored so that it uses the real
river.Client
insert path, and also uses the same job execution path as real execution. This minimizes the potential for differences in behavior between testing and real execution.
PR #766. -
Adjusted panic stack traces to filter out irrelevant frames like the ones generated by the runtime package that constructed the trace, or River's internal rescuing code. This makes the first panic frame reflect the actual panic origin for easier debugging. PR #774.
Fixed
v0.17.0
Added
- Exposed
TestConfig
struct onConfig
under theTest
field for configuration that is specific to test environments. For now, the only field on this type isTime
, which can be used to set a syntheticTimeGenerator
for tests. A stubbable time generator was added asrivertest.TimeStub
to allow time to be easily stubbed in tests. PR #754. - New
rivertest.Worker
type to make it significantly easier to test River workers. Either real or synthetic jobs can be worked using this interface, generally without requiring any database interactions. TheWorker
type provides a realistic execution environment with access to the full range of River features, includingriver.ClientFromContext
, middleware (both global and per-worker), and timeouts. PR #753.
Changed
- Errors returned from retryable jobs are now logged with warning logs instead of error logs. Error logs are still used for jobs that error after reaching
max_attempts
. PR #743. - Remove range variable capture in
for
loops and use simplifiedrange
syntax. Each of these requires Go 1.22 or later, which was already our minimum required version since Go 1.23 was released. PR #755.
Fixed
riverdatabasesql
driver: properly handlenil
values inbytea[]
inputs. This fixes the driver's handling of empty unique keys on insert for non-unique jobs with the newer unique jobs implementation. PR #739.JobCompleteTx
now returnsrivertype.ErrNotFound
if the job doesn't exist instead of panicking. PR #753.