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

5
我有一个Web应用程序,需要执行一个耗时较长的过程(通常需要1分钟左右)。
我来简要解释一下:在我的应用程序中,我有一个算法根据一些参数(主要是日期)为一组对象分配外键。当用户按下应用程序内指定的按钮时,会执行一个控制器方法。在该方法内,我调用模型中处理所有逻辑并分配密钥的方法。如前所述,整个过程大约需要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

ActiveJob 应该能够处理这个。虽然我很好奇自定义外键过程的目的是什么,为什么需要花费一分钟? - Schwern
2个回答

5

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

首先,您可以使用Rails生成器来创建一个:

rails generate job slow_algorithm

这将会在app/jobs/slow_algorithm_job.rb下创建一个任务。在那里,你可以编写你的算法逻辑。

将任务加入队列也很容易,只需要在你的控制器中执行:

SlowAlgorithmJob.perform_later

您需要解决的最后一件事是设置队列后端,以实际运行作业。Rails支持多种后端。可能最简单的设置方法是delayed_job,但如果您正在寻找更可伸缩性的选择,我建议尝试Sidekiq
编辑:如何通知用户作业已完成?
为此,您必须明确地跟踪任务的进度。一个可能的方向是创建一个记录,我们称之为“任务”,它表示您算法的一个调用。
当用户触发应该排队作业的操作时,将创建具有状态“待处理”的Task记录,然后可以使用before_perform和after_perform作业钩子将Task状态移动到“运行中”,然后移动到“已完成”。
after_perform钩子可用于通知客户。应用程序将如何执行这一点取决于您。例如,Dropbox在下载大量文件时使用类似的系统。他们排队作业,压缩文件,然后发送带有下载链接的电子邮件一旦作业完成。
另一种方法是使用应用程序内通知系统。
最后,为了使通知弹出窗口而不需要用户刷新页面,您必须使用ActiveCable,并使用after_perform钩子将通知推送回用户。

1
我更新了答案,并提供了一个建议,如何实现这个。加油! - Mladen Ilić

2
我建议使用sidekiq作为后台任务的更好解决方案

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接