ruby-on-rails - 如何使用延迟作业在 Rails 中执行异步任务?

标签 ruby-on-rails ruby asynchronous delayed-job rails-activejob

任务: 以Async方式删除项目[作业]

我已经在我的 Rails 应用程序中使用 delayed_jobs 配置了 Active jobs,但我仍然对在 Rails 项目中执行 Async 任务感到困惑。

举个例子: 我有一些项目要从数据库中删除,但我想以 Async 方式进行。我还在 delayed_job 博客中阅读了有关 perform_laterperform_now 方法的内容。这是我的代码,运行良好:

Controller 类

 def destroy
   PostJob.perform_now(params[:id])
   respond_to do |format|
    format.xml  { head :ok }
    format.js { render 'posts.js.erb' }
  end
 end

工作类别

class PostJob < ActiveJob::Base
 queue_as :default

 def perform(id)
  @post = Post.find(id)
  @post.destroy
 end
end

根据 official doc delayed_jobs 我可以在方法末尾添加 handle_asynchronouslyasync 方式运行。在这种情况下我该如何实现?

我的问题:

  1. 当我查看destroy 方法时,它并没有以Async 方式删除元素。然而,在destroy 方法中编写的每个步骤都是在Synchronous 中。我错了吗?
  2. 如果不是,那么如何实现 destroy 方法以异步方式删除 post
  3. 后台任务和 cron 作业是一回事吗?

编辑-1

在 A Fader Darkly 给出建议后,我将 perform_now 更改为 perform_later,这对于 Async 进程非常有效,但它没有删除从表中输入(代码很好,因为它在我使用 perform_now 时有效)。

此外,当我通过以下命令手动运行作业时,一切正常:

rake jobs:work

有什么方法可以在 queue 获得一些新数据后立即执行 delay_job 任务?

最佳答案

如果您将 destroy 方法更改为调用:

PostJob.perform_later(params[:id])

它应该异步发生。如果没有,您还需要进行更多设置。

对于您的问题:

  1. 是的,你是对的,但你说的是同义反复。该方法中的所有内容都是同步的 - 由于 perform_now,作业队列未被使用。因此 destroy 不是以异步方式删除。
  2. 见上文。
  3. Cron 作业在操作系统级别运行,并在特定时间定期安排。例如,您可以让 cron 作业每分钟、每天或每周(特定日期的特定时间)运行。它们从称为 crontab 的计划文件运行。

“后台”任务只是阻止它接管终端 session 的 IO。因此,当进程在后台运行时,您可以继续使用终端。通常这是临时完成的,因此您不必等待繁重的操作完成就可以继续执行不同的任务。

编辑

根据对问题的编辑,听起来需要启动 Delayed Job 守护进程。来自说明:

注意:对于 Rails 4,将 script/delayed_job 替换为 bin/delayed_job 在本地运行队列时,省略命令的“RAILS_ENV=production”部分。

运行作业 script/delayed_job 可用于管理将开始处理作业的后台进程。

为此,将 gem“daemons”添加到您的 Gemfile 并确保您已运行 rails generate delayed_job。

然后您可以执行以下操作:

RAILS_ENV=production script/delayed_job start RAILS_ENV=production script/delayed_job stop

在不同的进程中运行两个 worker。

RAILS_ENV=production script/delayed_job -n 2 start RAILS_ENV=production script/delayed_job stop

设置 --queue 或 --queues 选项以从特定队列工作。

RAILS_ENV=production script/delayed_job --queue=tracking start RAILS_ENV=production script/delayed_job --queues=mailers,tasks start

使用 --pool 选项指定工作池。您可以多次使用此选项来为不同的队列启动不同数量的工作人员。

以下命令将为跟踪队列启动 1 个 worker,

2 个 worker 用于邮件程序和任务队列,2 个 worker 用于任何作业:

RAILS_ENV=production script/delayed_job --pool=tracking --pool=mailers,tasks:2 --pool=*:2 开始

运行所有可用的作业然后退出

RAILS_ENV=production script/delayed_job start --exit-on-complete

或者在前台运行

RAILS_ENV=production script/delayed_job run --exit-on-complete

关于ruby-on-rails - 如何使用延迟作业在 Rails 中执行异步任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31136837/

相关文章:

ruby-on-rails - Rails 表单发出 GET 请求而不是 POST 请求

ruby-on-rails - Unit::Test 与 Rspec 之间的区别

ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法?

Ruby 不同的行为取决于 block 类型

mysql - 在开发环境中使用Mysql原生函数和ActiveRecord

ruby-on-rails - 数组 will_paginate rspec 的未定义方法 total_pages'

ruby-on-rails - rake 数据库 :migrate returning error rake db:migrate

javascript - 等待异步函数完成而不添加回调

javascript - 异步 Node.JS 中的用户输入

c# - 使用 .net 4.5 在 C# 中发布 json 异步时保持 UI 功能