Skip to content

v0.16.0

Latest

Choose a tag to compare

@kvet kvet released this 05 Oct 17:04
v0.16.0
591fda4

What's Changed

Queuert 0.16 rebuilds the job model around the chain's head row and reworks attempt handling around a single finish outcome API, with a one-step schema migration from v0.15.1. It also brings faster listing queries, a redesigned dashboard, and a leaner, more consistent public API. This release contains many breaking changes — review the notes below before upgrading.

Breaking Changes

  • New job model — a chain's head row is now the chain itself. ChainStatus is just running | completed; completed jobs carry continuedToId; running jobs expose attemptAt / attemptBy / attemptUntil. "Lease" is renamed to "attempt" throughout (leaseConfig → attemptConfig with timeoutMs / heartbeatMs, LeaseConfig → AttemptConfig, plus matching log events and metrics).
  • Attempt finalization — handlers end an attempt with complete(async ({ finish }) => finish({ output | continueWith | reschedule })). rescheduleJob() and RescheduleJobError are removed; rescheduling is now a non-error outcome. completeChain's complete option is renamed to handler.
  • Renames — startChain / startChains → createChain / createChains.
  • Listing API reshaped — flat options with a single status, required typeName, status-dependent orderBy checked at compile time, root → independent; the chainId / jobId / chainTypeName filters are removed; CreatedAtCursor → TimestampWithIdCursor.
  • Deduplication — scope is now required and "incomplete" is renamed to "running" (missing or unknown scopes throw TypeError). windowMs and excludeChainIds are removed.
  • Caller-supplied id collisions now throw instead of being silently ignored.
  • cascade removed from deleteChain / deleteChains.
  • TransactionContextRequiredError removed — a plain Error is thrown instead.
  • wrapHandler now wraps the whole attempt, so a catch around next() observes handler failures.
  • Public type exports pruned — internal helper types are no longer exported; CompletedJob and AttemptConfig are newly exported.

Database Migrations (@queuert/postgres, @queuert/sqlite)

  • All migrations are collapsed into 001_initial_schema. You must be on v0.15.1 before upgrading.
  • PostgreSQL: the upgrade copies tables while v0.15.1 workers keep running; a migration_lock table makes concurrent migrateToLatest() calls safe.
  • SQLite: stop all workers and clients before running the migration.
  • vacuum() is removed, along with SQLite's checkForeignKeys / checkAutoVacuum options.

Features

  • step transaction primitive inside attempt handlers, with a matching wrapStep middleware hook.
  • Batched lookups — getChains / getJobs, with ChainTypeMismatchError.
  • Type names & counts — listChainTypeNames / listJobTypeNames and countByChainTypeNames / countByJobTypeNames.
  • Worker shutdown signal — in-flight handlers receive "worker_stopping" as the abort reason when the worker stops.

Dashboard

  • Full UI redesign: Overview page, Find by ID (⌘K), status tabs, and themes.
  • New endpoints for type names, counts, and by-ID lookups. Malformed IDs and unknown /api paths return 404; uncaught errors return 500 with an { error } body.

Observability (@queuert/otel)

  • Attempt spans record an abort event; prepare / step / complete spans record exceptions and ERROR status.
  • Breaking: blocker-completion span renamed resolve chain.* → complete chain.*; queuert.attempt.result attribute removed (read the outcome from span status); metric names follow the lease → attempt rename.
  • @opentelemetry/api peer dependency now also accepts ^1.0.0.

Performance & Fixes

  • Faster listing queries via per-type anchoring.
  • PostgreSQL and SQLite skip the redundant RELEASE SAVEPOINT round-trip.
  • Type checking is roughly 20–40% cheaper.
  • AttemptMiddleware typed against a concrete adapter now works.
  • chain.input now correctly reflects the entry job's input.
  • Fixed a race where a job created with blockers could start pending instead of blocked (#4).

Packages

All packages released at 0.16.0: queuert, @queuert/postgres, @queuert/sqlite, @queuert/redis, @queuert/nats, @queuert/otel, @queuert/dashboard.