Rails Async Active Job doesn't execute code, while inline does

时间:2016-07-11 20:20:29

标签: ruby-on-rails ruby-on-rails-5 rails-activejob

Does the :async queue adapter actually do anything?

:inline, which is what is default in Rails 4, processes jobs built with ActiveJob, uh... inline, in the current execution thread. Async, shouldn't. It should use the ConnectionPool to not run it in the current thread, and that's ideally what would be happening. It'd run perform outside of the current execution thread.

But nothing executes it.

I've pored through the docs, and the only thing I can fathom is is that :async, unlike :inline, doesn't execute tasks, and expects you to build a system around execution locally. I have to manually perform perform on all jobs in order to get them to execute locally. When I set the adapter to :inline, it works just fine without having to execute.

Is there some configuration issue I'm missing that's preventing async from working correctly (like ActionCable?).

Does it not work if executed from a rake task (or the console?).

It works fine with :sidekiq/:resque, but I don't want to be running these locally all the time.

Rails by default comes with an "immediate runner" queuing implementation. That means that each job that has been enqueued will run immediately.

This is kind of what's cueing me in there being something wrong. I have jobs that are sitting in a queue somewhere that just don't run. What could be stopping this?

2 个答案:

答案 0 :(得分:5)

这是我发现的。随着并发ruby的出现,rake任务没有设置来处理这个问题。

如果你在文档中读到了:async,它会在进程结束时被清除。

  

Rails本身只提供进程中的排队系统,仅限于此   将作业保存在RAM中。如果进程崩溃或机器重置,   然后使用默认的异步后端丢失所有未完成的作业。

Rake流程在结束时结束。因此,如果您正在进行任何类型的数据更改,rake任务将无法打开足够长的时间来运行作业,这就是为什么它们运行:inline就好了,而不是:async

所以,我还没有想出一个解决办法,让rake任务保持足够长的时间来运行:async {并保持应用:async整个时间。我必须将其切换到:inline以运行任务,然后在我完成其余工作时返回:async。这就是它与:sidekiq:resque一起工作的原因,因为这些应用程序将作业信息保存在内存中,并且在rake任务结束时不会释放。

为了让rake任务在本地与:async一起使用,除了rake(作为任务运行员)了解如何在本地工作之外,除了:inline以外,除了运行任务之外没有太多可以做的事情。在启动(或不启动)异步任务时保持打开状态。作为一项仅限开发的功能,这不是真正的高优先级,但是,如果你正在抨击桌面而不理解为什么:async默认情况下运行作业的任务实际上不会运行,那就是原因。< / p>

答案 1 :(得分:1)

在退出rake任务之前,您可以在rake任务结束时等待AsyncAdapter完成处理:

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