Rails测试环境下如何让延迟函数延迟
How to allow delayed function to be delayed in Rails test environment
我有一个 Rails 模型 class,它有一个稍后要执行的功能,由 Delayed::Job
管理。这是函数(简化):
def fn_with_dj_delay
puts "puts output here"
do_somethting_else
end
handle_asynchronously :fn_with_dj_delay, :run_at => Proc.new { 24.hours.from_now }, :queue => 'my_queue'
但是,当在我的 Rails 测试环境中调用该函数时,将跳过延迟。这是否有可能在两种环境中执行相同的操作?
在 rails c test
中,函数会立即触发。这是一个稍微简化和截断的控制台日志:
2.3.1 :004 > x = MyClass.new
2.3.1 :005 > x.save!
2.3.1 :006 > x.fn_with_dj_delay
puts output here
=> #<Delayed::Backend::ActiveRecord::Job id: nil, priority: 0, attempts: 0 # ...
2.3.1 :007 > Delayed::Job.last
Delayed::Backend::ActiveRecord::Job Load (0.3ms) SELECT `delayed_jobs`.* # ...
=> nil
在rails c
中,该功能会按照指示自动延迟。同样,稍微简化和截断的控制台日志:
2.3.1 :004 > x = MyClass.new
2.3.1 :005 > x.save!
2.3.1 :006 > x.fn_with_dj_delay
(0.2ms) BEGIN
SQL (0.4ms) INSERT INTO `delayed_jobs` (`handler`, `run_at`, # ...
(0.5ms) COMMIT
=> true
2.3.1 :007 > Delayed::Job.last
Delayed::Backend::ActiveRecord::Job Load (2.2ms) SELECT `delayed_jobs`.* # ...
=> #<Delayed::Backend::ActiveRecord::Job id: 1, priority: 0, attempts: 0 # ...
我能看到的唯一线索是函数完成时在测试控制台中返回的、未实例化的 Delayed::Backend::ActiveRecord::Job
对象。如果该对象有一些无效的地方,我可以理解这种失败,尽管我希望会引发错误。无论如何,这不是问题:
2.3.1 :004 > res = p.check_for_similar_web_data
puts output here
=> #<Delayed::Backend::ActiveRecord::Job id: nil, priority: 0, attempts: 0 # ...
2.3.1 :005 > res.valid?
=> true
2.3.1 :006 > res.save!
(0.1ms) BEGIN
SQL (0.4ms) INSERT INTO `delayed_jobs` (`handler`, `run_at` # ...
(0.5ms) COMMIT
=> true
这太简单了,我很惊讶和尴尬我在写这篇文章之前没有找到它。估计测试环境默认是false
?
2.3.1 :003 > Delayed::Worker.delay_jobs = true
2.3.1 :004 > x = MyClass.new
2.3.1 :005 > x.save!
2.3.1 :006 > x.fn_with_dj_delay
(0.2ms) BEGIN
SQL (0.4ms) INSERT INTO `delayed_jobs` (`handler`, `run_at`, # ...
(0.5ms) COMMIT
=> true
2.3.1 :007 > Delayed::Job.last
Delayed::Backend::ActiveRecord::Job Load (2.2ms) SELECT `delayed_jobs`.* # ...
=> #<Delayed::Backend::ActiveRecord::Job id: 1, priority: 0, attempts: 0 # ..
我有一个 Rails 模型 class,它有一个稍后要执行的功能,由 Delayed::Job
管理。这是函数(简化):
def fn_with_dj_delay
puts "puts output here"
do_somethting_else
end
handle_asynchronously :fn_with_dj_delay, :run_at => Proc.new { 24.hours.from_now }, :queue => 'my_queue'
但是,当在我的 Rails 测试环境中调用该函数时,将跳过延迟。这是否有可能在两种环境中执行相同的操作?
在 rails c test
中,函数会立即触发。这是一个稍微简化和截断的控制台日志:
2.3.1 :004 > x = MyClass.new
2.3.1 :005 > x.save!
2.3.1 :006 > x.fn_with_dj_delay
puts output here
=> #<Delayed::Backend::ActiveRecord::Job id: nil, priority: 0, attempts: 0 # ...
2.3.1 :007 > Delayed::Job.last
Delayed::Backend::ActiveRecord::Job Load (0.3ms) SELECT `delayed_jobs`.* # ...
=> nil
在rails c
中,该功能会按照指示自动延迟。同样,稍微简化和截断的控制台日志:
2.3.1 :004 > x = MyClass.new
2.3.1 :005 > x.save!
2.3.1 :006 > x.fn_with_dj_delay
(0.2ms) BEGIN
SQL (0.4ms) INSERT INTO `delayed_jobs` (`handler`, `run_at`, # ...
(0.5ms) COMMIT
=> true
2.3.1 :007 > Delayed::Job.last
Delayed::Backend::ActiveRecord::Job Load (2.2ms) SELECT `delayed_jobs`.* # ...
=> #<Delayed::Backend::ActiveRecord::Job id: 1, priority: 0, attempts: 0 # ...
我能看到的唯一线索是函数完成时在测试控制台中返回的、未实例化的 Delayed::Backend::ActiveRecord::Job
对象。如果该对象有一些无效的地方,我可以理解这种失败,尽管我希望会引发错误。无论如何,这不是问题:
2.3.1 :004 > res = p.check_for_similar_web_data
puts output here
=> #<Delayed::Backend::ActiveRecord::Job id: nil, priority: 0, attempts: 0 # ...
2.3.1 :005 > res.valid?
=> true
2.3.1 :006 > res.save!
(0.1ms) BEGIN
SQL (0.4ms) INSERT INTO `delayed_jobs` (`handler`, `run_at` # ...
(0.5ms) COMMIT
=> true
这太简单了,我很惊讶和尴尬我在写这篇文章之前没有找到它。估计测试环境默认是false
?
2.3.1 :003 > Delayed::Worker.delay_jobs = true
2.3.1 :004 > x = MyClass.new
2.3.1 :005 > x.save!
2.3.1 :006 > x.fn_with_dj_delay
(0.2ms) BEGIN
SQL (0.4ms) INSERT INTO `delayed_jobs` (`handler`, `run_at`, # ...
(0.5ms) COMMIT
=> true
2.3.1 :007 > Delayed::Job.last
Delayed::Backend::ActiveRecord::Job Load (2.2ms) SELECT `delayed_jobs`.* # ...
=> #<Delayed::Backend::ActiveRecord::Job id: 1, priority: 0, attempts: 0 # ..