Skip to content

Keep concurrency locks across non-graceful job release - #771

Open
rafael-pissardo wants to merge 1 commit into
rails:mainfrom
rafael-pissardo:fix/735-concurrency-bypass-after-force-kill
Open

Keep concurrency locks across non-graceful job release#771
rafael-pissardo wants to merge 1 commit into
rails:mainfrom
rafael-pissardo:fix/735-concurrency-bypass-after-force-kill

Conversation

@rafael-pissardo

@rafael-pissardo rafael-pissardo commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Extend a job's concurrency semaphore expiry when a claimed execution is released back to ready, so the slot stays owned across restart
  • Skip expiring semaphores whose key still has a ready job, and run concurrency maintenance synchronously at supervisor boot and dispatcher start before workers can poll
  • Add regression tests for the ready-job lock race from non-graceful shutdown

Fixes #735.

Test plan

  • TARGET_DB=sqlite bundle exec ruby -Itest test/unit/concurrency_maintenance_test.rb
  • TARGET_DB=sqlite bundle exec ruby -Itest test/integration/concurrency_controls_test.rb
  • TARGET_DB=sqlite bundle exec ruby -Itest test/models/solid_queue/claimed_execution_test.rb
  • TARGET_DB=sqlite bundle exec ruby -Itest test/unit/dispatcher_test.rb
  • TARGET_DB=sqlite bundle exec ruby -Itest test/unit/fork_supervisor_test.rb
  • RuboCop on changed files

When a claimed concurrency-limited job is released back to ready after a
force-kill, its semaphore could expire and maintenance could unblock
another job for the same key while the released job was still ready.
Workers then claimed both and broke limits_concurrency.

Extend the lock on release, skip expiring semaphores still held by ready
jobs, run concurrency maintenance synchronously at supervisor boot and
dispatcher start, and cover the race with unit tests.
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.

limits_concurrency bypassed after non-graceful shutdown

1 participant