Skip to content

Fix rivertest.Worker ignoring Config.JobStuckThreshold - #1418

Merged
brandur merged 3 commits into
riverqueue:masterfrom
toruiwasa:fix/rivertest-stuck-threshold
Oct 1, 2026
Merged

brandur merged 3 commits into
riverqueue:masterfrom
toruiwasa:fix/rivertest-stuck-threshold

Conversation

@toruiwasa

Copy link
Copy Markdown
Contributor

When a job worked by rivertest.Worker gets stuck, the Job appears to be stuck warning is logged 5 seconds after the job's timeout regardless of Config.JobStuckThreshold. A real client uses the configured threshold, which defaults to 10 seconds.

#1291 added JobStuckThreshold and passed it to the job executor from the producer only. rivertest.Worker builds the same executor and already passes JobTimeout through, but it leaves StuckThresholdOverride unset, so the executor falls back to its internal 5 second default. This passes w.config.JobStuckThreshold, which NewWorker has already defaulted. If keeping 5 seconds in rivertest was intentional, let me know and I'll document that instead.

The new subtest uses the same 1ms threshold and 10ms timeout as the producer's JobStuckHandler test, and only waits for the warning to be logged, about 11ms in. Like that test, it doesn't check timing: without the fix it fails locally at the 3 second WaitTimeout(), but with GITHUB_ACTIONS=true, where WaitTimeout() is 10 seconds, it still passes after about 5 seconds.

Locally, -race on rivertest and golangci-lint run pass.

Claude Code assisted with diagnosing the problem, implementing the fix, and writing the test.

`rivertest.Worker` builds a `JobExecutor` without setting `StuckThresholdOverride`, so stuck job detection always used the executor's internal 5 second default and ignored `Config.JobStuckThreshold`. The producer has passed the configured value, which defaults to 10 seconds, since riverqueue#1291 added the setting.

Pass `w.config.JobStuckThreshold` the same way the producer does. `NewWorker` already runs the config through `WithDefaults`, so an unset threshold becomes the 10 second default without any extra handling here.
Nothing in `rivertest` covered stuck job detection. The new subtest sets a 1ms threshold and a 10ms timeout, the same values as the producer's `JobStuckHandler` test, and has the worker wait until the `Job appears to be stuck` log line is written. The test worker's stuck callback is a no-op, so the log is the only signal available.

The test doesn't assert on timing. Without the fix the log line comes after about 5 seconds, which fails against the local 3 second `WaitTimeout()` but not against the 10 second one used on GitHub Actions. An upper bound on elapsed time would catch that on CI too, but would be a timing-sensitive assertion that a slow runner could trip.

It's only under `TestWorker_Work` because the threshold is applied in `workJob`, which `Work` and `WorkJob` both go through.

@brandur brandur left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great. Thanks Toru!

@brandur
brandur merged commit c40490c into riverqueue:master Oct 1, 2026
12 checks passed
brandur added a commit that referenced this pull request Oct 1, 2026
Minor tweak to #1418. This was note in the PR description, but the
`WaitOrTimeout` helper allows ten seconds timeout in GitHub's CI. The
test's executor only waits five seconds, so it'll never fail in CI.

Deconstruct the `WaitOrTimeout` so that we can fail after only three
seconds.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants