Closed
Description
If a background job created using perform_later exceeds the concurrency limit in the test environment it will get stuck in a loop:
- perform_later is called
- The job is executed immediately because it's running in a test environment (
execution_mode = :inline
) - The job throws ConcurrencyExceededError
- The job is re-queued with a delay
- goto 2
This is tangentially related to #591, which was initially addressed in #593 by having the job skip concurrency limits if perform_now is used. I would expect perform_later/retry_job to ignore the limit the same way when executing inline.
Example code:
class InfiniteLoopTestJob < ActiveJob::Base
include GoodJob::ActiveJobExtensions::Concurrency
queue_as :bug_repro_job
good_job_control_concurrency_with(
total_limit: 2,
perform_limit: 1,
key: "key"
)
def perform(*args)
ap "jobs to queue: #{$jobs_to_queue}"
$jobs_to_queue -= 1
return if $jobs_to_queue < 0
InfiniteLoopTestJob.perform_later
end
end
(Run this task with RAILS_ENV=test)
namespace :infinite_loop_test do
task :run => :environment do
$jobs_to_queue = 5
ap "starting task"
InfiniteLoopTestJob.perform_later
end
end
Output:
"starting task"
"jobs to queue: 5"
rails aborted!
SystemStackError: stack level too deep
/home/user/git_repos/repo/app/jobs/infinite_loop_test_job.rb:17:in `perform'
/home/user/git_repos/repo/lib/tasks/infinite_loop_test.rake:9:in `block (2 levels) in <main>'
/home/user/git_repos/repo/bin/rails:5:in `<top (required)>'
/home/user/git_repos/repo/bin/spring:10:in `block in <top (required)>'
/home/user/git_repos/repo/bin/spring:7:in `tap'
/home/user/git_repos/repo/bin/spring:7:in `<top (required)>'
Tasks: TOP => infinite_loop_test:run
(See full trace by running task with --trace)
Metadata
Assignees
Labels
No labels
Activity