Repository navigation
hammerwork 2.2.0
A fix and cleanup release. It is a minor version because it adds public API with default
implementations: DatabaseQueue::start_claimed_run; in hammerwork-web,
JobHistory::running_jobs, job_states and count_archivable, and
SortParams::is_ascending. Nothing existing changes, and the internals were simplified
without changing behaviour (#95).
Fixed
- A failed fail-fast batch no longer runs the jobs a batch-mode worker already
claimed. When aJobBatchwithPartialFailureMode::FailFastfailed, only its
Pendingjobs were failed; the jobs of it that a worker withwith_batch_size(n)had
claimed but not started wereRunning, so they still ran. Before starting a held job
the worker now checks (at most once per poll interval, with the pause check) whether
its batch has failed and, if so, fails it as the batch fails itsPendingjobs
(Failed, not retried) instead of running it. Held jobs of a failed batch are failed
rather than released on a pause or shutdown too. - Batch-mode processing times no longer include the time a job waited in its batch.
A batch claim stamps every job'sstarted_atwith the claim time, so durations
computed fromstarted_at(queue statistics, dashboard and CLI averages) counted the
wait of held jobs as processing time. A held job that waited now records its actual
start when it starts, through the newDatabaseQueue::start_claimed_run(default:
renew the lease only, as before). - A held batch job skipped because its lease was lost refunds its rate limit token,
as released jobs already did, so a lost claim no longer spends the rate limit. - Dashboard live updates report jobs that go from
Runningback toPending. A
retry, a stale job requeued by the reaper and a claimed job released by a batch-mode
worker change none of the timestampsJobHistory::recent_job_changesreads, so
WebSocket clients subscribed tojob_updateswere never told. The live-update poller
now tracks the running jobs (newJobHistory::running_jobs) and reads the state of the
ones that stopped running without such a timestamp (newJobHistory::job_states),
reporting them at the poll that saw the change. No schema change is needed. - The dashboard's uptime no longer wraps to a huge number if the clock goes backwards
(/api/stats/overview,/api/system/info);SystemState::uptime_secondsis never
negative. - The dashboard's job list sorts ascending for
sort_order=ASC(any case), not only
for lowercaseasc, like the other endpoints. - An archive dry run (
POST /api/archive/jobswithdry_run: true) reports how many
jobs a real run would archive instats.jobs_archived(new
JobHistory::count_archivable) instead of zeroed statistics. cargo hammerwork backup create/restoreandmigration statushonour
connect_timeout_secs. They connected with the default 10-second timeout whatever
the configuration said.cargo hammerwork maintenance vacuumreports the jobs it actually deleted, not the
counts taken before the deletes (jobs can change in between).cargo hammerwork maintenance dead-jobsdescribes what it selects:Runningjobs
that started more than--stale-hoursago, not jobs with "no update" for that long.cargo hammerwork monitor dashboardshows icons forRetryingandTimedOutjobs.cargo hammerwork webhook update --namerefuses a name another webhook already
has, aswebhook adddoes.- Pausing a queue stops batch-mode workers from starting the jobs they hold. A worker
withwith_batch_size(n)kept starting the claimed jobs of its current batch after the
queue was paused, up tonmore jobs, contrary to "paused queues are honoured". Before
starting a held job it now checks the pause (at most once per poll interval) and, when
the queue is paused, hands the unstarted jobs back toPendingwithout counting an
attempt, as on shutdown. Running jobs finish. - A weighted batch claim no longer loses jobs it already claimed. With weighted
priorities,dequeue_batch_leasedclaims level by level; when a later level's claim
failed (a dropped connection, or a MySQL deadlock past its retries), the error was
returned and the jobs claimed from earlier levels were dropped. They stayedRunning
until their leases expired, with an attempt spent, so a job on its last attempt went to
Deadwithout having run. The claimed jobs are now returned (and the error logged), as
the trait's default implementation already did. - A job row that cannot be decoded no longer stops the stale job reaper. On MySQL any
such row among the staleRunningjobs, and on PostgreSQL one that was out of
attempts, maderequeue_stale_jobsfail and roll back, so no stale job of any queue
was reclaimed while the row existed. The reaper now reclaims it like any other (back
toPending, orDeadwith a warning that its dependents, workflow, batch and
recurring schedule could not be updated). - A job row that cannot be decoded no longer blocks a MySQL queue. It stayed
Pendingat the head of the queue: every single claim failed on it, and batch claims of
one job came back empty forever. MySQL now claims it, as PostgreSQL does (a single claim
returns the decoding error, a batch claim skips it), so the jobs behind it run; it stays
Runninguntil its lease expires and the reaper takes it. Such rows come from corrupt
data or a newer version's data (for example a retry strategy this version does not
know).