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

时间:2018-11-23 16:13:21

标签: ruby-on-rails ruby-on-rails-5 background-process

我有一个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 %>

my_controller.rb:

def button_method
  Object.execute_algorithm(@variable)
  redirect_to :back
end

Object.rb:

def self.execute_algorithm(variable)
  # Logic
end

2 个答案:

答案 0 :(得分:4)

Rails使用ActiveJob,它使您可以将昂贵的任务排队并在后台运行它们。它们非常易于使用。

拳头,您可以使用rails生成器创建一个:

rails generate job slow_algorithm

...这将在app/jobs/slow_algorithm_job.rb下创建工作。在那里,您可以实现算法逻辑。

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

SlowAlgorithmJob.perform_later

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

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

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

当用户触发应使作业排队的操作时,将创建状态为pending的任务记录,然后可以使用before_performafter_perform作业挂钩来移动{{1 }}状态更改为Task,然后更改为running

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

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

最后,要弹出通知而不需要用户刷新页面,您必须使用after_perform并再次使用ActiveCable钩子将通知推回用户。 / p>

答案 1 :(得分:1)

我会建议sidekiq作为针对后台任务的更好的解决方案