Skip to content

Commit 9c6f2bc

Browse files
authored
Merge pull request #36 from davue/master
Start jobs outside of transaction that is locking the job
2 parents 351dbe0 + 78055ba commit 9c6f2bc

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Workhorse Changelog
22

3+
## Unreleased
4+
5+
* Fix race-condition in polling mechanism which could result in workers
6+
trying to run a job that is not yet locked.
7+
8+
Sitrox reference: #128333.
9+
310
## 1.3.0.rc3 - 2025-06-10
411

512
* Require Rails 7.0.0 or later

lib/workhorse/poller.rb

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,9 @@ def poll
257257

258258
timeout = [MIN_LOCK_TIMEOUT, [MAX_LOCK_TIMEOUT, worker.polling_interval].min].max
259259
with_global_lock timeout: timeout do
260-
Workhorse.tx_callback.call do
261-
job_ids = []
260+
job_ids = []
262261

262+
Workhorse.tx_callback.call do
263263
# As we are the only thread posting into the worker pool, it is safe to
264264
# get the number of idle threads without mutex synchronization. The
265265
# actual number of idle workers at time of posting can only be larger
@@ -281,9 +281,14 @@ def poll
281281
worker.log 'Rolling back transaction to unlock jobs, as worker has been shut down in the meantime'
282282
fail ActiveRecord::Rollback
283283
end
284-
285-
job_ids.each { |job_id| worker.perform(job_id) }
286284
end
285+
286+
# This needs to be outside the above transaction because it runs the job
287+
# in a new thread which opens a new connection. Even though it would be
288+
# non-blocking and thus directly conclude the block and the transaction,
289+
# there would still be a risk that the transaction is not committed yet
290+
# when the job starts.
291+
job_ids.each { |job_id| worker.perform(job_id) } if running?
287292
end
288293
end
289294

0 commit comments

Comments
 (0)