:异步队列适配器实际上有什么作用吗?
:inline,这是 Rails 4 中的默认设置,在当前执行线程中处理使用 ActiveJob 构建的作业,呃...内联。异步,不应该。它应该使用 ConnectionPool 来不在当前线程中运行它,这就是理想情况下会发生的情况。它会在当前执行线程之外运行执行。
但是没有任何东西执行它。
我已经仔细阅读了文档,我唯一能理解的是:async 与 :inline 不同,它不执行任务,并且期望您围绕本地执行构建一个系统。我必须对所有作业手动执行
perform
才能让它们在本地执行。当我将适配器设置为 :inline 时,它无需执行即可正常工作。
我是否遗漏了一些配置问题,导致异步无法正常工作(如 ActionCable?)。
如果从 rake 任务(或控制台?)执行,它不起作用吗?
它与 :sidekiq/:resque 配合得很好,但我不想一直在本地运行这些。
Rails by default comes with an "immediate runner" queuing implementation. That means that each job that has been enqueued will run immediately.
这就是在暗示我出了什么问题。我有一些工作在队列中,只是没有运行。什么可以阻止这一切?
这是我发现的。随着并发 ruby 的出现,rake 任务并没有设置来处理这个问题。
如果您阅读文档,它会显示
:async
,当进程结束时,它会从内存中清除。
Rails 本身只提供了一个进程内排队系统,该系统只 将作业保留在 RAM 中。如果进程崩溃或机器重置, 那么默认的异步后端所有未完成的作业都会丢失。
Rake 进程结束后也会结束。因此,如果您正在进行任何类型的数据更改,rake 任务将不会打开足够长的时间来运行作业,这就是为什么它们运行
:inline
很好,但不是 :async
。
所以,我还没有找到一个解决方案来保持 rake 任务打开足够长的时间来运行某些东西
:async
(并始终保持应用程序 :async
)。我必须将其切换到 :inline
来运行任务,然后在完成其余工作后切换回 :async
。这就是为什么它可以与 :sidekiq
或 :resque
配合使用,因为这些应用程序将作业信息保留在内存中,并且在 rake 任务结束时不会释放。
为了让 rake 任务在本地使用
:async
,如果你是本地的,除了以 :inline
的方式运行任务之外,你无能为力,直到 rake(作为任务运行程序)了解如何在异步任务执行时保持打开状态。已启动(或未启动)。作为仅用于开发的功能,这并不是真正的高优先级,但是,如果您在桌子上敲头,不明白为什么 :async
默认情况下运行作业的任务实际上不会运行,这就是原因。
您可以在 rake 任务末尾放置以下内容,以等待 AsyncAdapter 完成处理,然后再退出 rake 任务:
if Rails.configuration.active_job.queue_adapter == :async
executor =
ActiveJob::Base._queue_adapter.instance_eval do
@scheduler.instance_eval { @async_executor }
end
sleep(0.1) while executor.scheduled_task_count > executor.completed_task_count
end
Rails Perform_enqueued_jobs 也可能有帮助。您可以运行 :async 作业,但等待它们完成,而无需分配您自己的自定义适配器。
https://api.rubyonrails.org/v7.0.0/classes/ActiveJob/TestHelper.html
执行所有排队的作业。如果给定了一个块,则执行在该块的持续时间内排队的所有作业。如果未给出块,则执行测试中到目前为止的所有排队作业。
def test_perform_enqueued_jobs
perform_enqueued_jobs do
MyJob.perform_later(1, 2, 3)
end
assert_performed_jobs 1
end
def test_perform_enqueued_jobs_without_block
MyJob.perform_later(1, 2, 3)
perform_enqueued_jobs
assert_performed_jobs 1
end