在Rails 5中运行后台进程的最佳方法是什么?

Tob*_*sen 5 ruby-on-rails background-process ruby-on-rails-5

我有一个Web应用程序,我需要在其中执行需要一段时间才能完成的过程(通常需要1分钟)。

我将尝试简要地解释一下:在我的应用程序中,我有一个算法,该算法基于一堆参数(主要是日期)将外键分配给一组对象。当用户按下应用程序内的指定按钮时,将执行控制器方法。在该方法内部,我调用模型中的一种方法,在该方法中处理了所有逻辑并分配了键。如前所述,整个过程大约需要一分钟才能完成。

所以我的问题是:在Rails 5中在后台运行此过程的最佳方法是什么?我显然不想强迫我的用户等待一分钟,然后他们才能浏览应用程序,我也不希望浏览器在等待服务器响应时应用程序超时。那么解决这个问题的最佳方法是什么?我需要一个可以异步发出请求的框架吗?如果是这样,哪一个?(如果它不需要太多的依赖关系并且我可以继续使用ActiveRecord,我会更喜欢)。

我在ActionCable或AJAX方面并没有做太多工作,但是如果他们能以任何方式完成工作,那么我会很高兴知道如何做。

理想情况下,完成该过程后,我应该能够在应用内向用户发送通知

view.html.erb:

# Button the user presses to execute the algorithm
<%= link_to 'execute algorithm', algorithm_path(@variable), :method => :put %>
Run Code Online (Sandbox Code Playgroud)

my_controller.rb:

def button_method
  Object.execute_algorithm(@variable)
  redirect_to :back
end
Run Code Online (Sandbox Code Playgroud)

Object.rb:

def self.execute_algorithm(variable)
  # Logic
end
Run Code Online (Sandbox Code Playgroud)

Mla*_*lić 5

Rails 使用ActiveJob,它允许您将昂贵的任务排队并在后台运行它们。它们使用起来非常简单。

拳头,你可以使用 rails generator 来创建一个:

rails generate job slow_algorithm
Run Code Online (Sandbox Code Playgroud)

...这将在app/jobs/slow_algorithm_job.rb. 在那里,您可以实现您的算法逻辑。

排队工作同样简单,只需在您的控制器中完成:

SlowAlgorithmJob.perform_later
Run Code Online (Sandbox Code Playgroud)

您需要介绍的最后一件事是设置将实际运行作业的队列后端。Rails 支持其中的几个。可能最简单的设置是delay_job,但如果您正在寻找更具可扩展性的东西,我建议您查看Sidekiq。

编辑: 如何通知用户工作已完成?

为了做到这一点,您显然必须以某种方式跟踪任务的进度。一个可能的方向是创建一个记录,我们称之为 a Task,它代表您的算法的一次调用。

当用户触发应该排队作业的动作,任务记录与身份创建pending,然后before_perform与after_perform工作挂钩可用于移动Task状态running,然后到completed。

after_perform钩子可以用来通知客户。应用程序将如何执行,取决于您。例如,Dropbox 在下载大量文件时使用类似的系统。他们将作业排队,压缩文件,然后在作业完成后发送带有下载链接的电子邮件。

另一种方法是使用应用内通知系统。

最后,要在不需要用户刷新页面的情况下弹出通知,您必须ActiveCable再次使用after_perform钩子将通知推送回用户。