Skip to content

Commit 7c88af2

Browse files
committed
Start jobs outside of transaction that is locking the job to prevent race-condition on job state
1 parent b8a17fe commit 7c88af2

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

lib/workhorse/poller.rb

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

207207
timeout = [MIN_LOCK_TIMEOUT, [MAX_LOCK_TIMEOUT, worker.polling_interval].min].max
208208
with_global_lock timeout: timeout do
209-
Workhorse.tx_callback.call do
210-
job_ids = []
209+
job_ids = []
211210

211+
Workhorse.tx_callback.call do
212212
# As we are the only thread posting into the worker pool, it is safe to
213213
# get the number of idle threads without mutex synchronization. The
214214
# actual number of idle workers at time of posting can only be larger
@@ -230,9 +230,14 @@ def poll
230230
worker.log 'Rolling back transaction to unlock jobs, as worker has been shut down in the meantime'
231231
fail ActiveRecord::Rollback
232232
end
233-
234-
job_ids.each { |job_id| worker.perform(job_id) }
235233
end
234+
235+
# This needs to be outside the above transaction because it runs the job
236+
# in a new thread which opens a new connection. Even though it would be
237+
# non-blocking and thus directly conclude the block and the transaction,
238+
# there would still be a risk that the transaction is not committed yet
239+
# when the job starts.
240+
job_ids.each { |job_id| worker.perform(job_id) } if running?
236241
end
237242
end
238243

0 commit comments

Comments
 (0)