如何在Rails中的请求之间共享变量值?

时间:2019-02-06 15:34:01

标签: ruby-on-rails ajax

我正在使用Ruby on Rails 4.2。在控制器中,我有一种方法需要花费大量时间才能完成一些繁重的计算。我想通知用户计算进度。我的想法是让@progress变量在计算过程中进行更新,并由处理来自前端的AJAX请求的不同操作读取。但是这个想法失败了-当变量以long方法更新时,我总是在AJAX操作中使用默认值0。我试过@@ progress,$ progress和session [:progress],但结果完全一样。 现在,我正在考虑建立一个模型,用于在数据库中存储进度并从中读取进度,但是我不敢相信无法通过一些更简单的方法来完成。 请分享您的想法!

1 个答案:

答案 0 :(得分:3)

理论上:

在这些情况下,通常的方法是从HTTP处理程序进程异步执行作业(因此,最终用户等待Web服务器响应的时间不会太长)。

这意味着:

  1. 将繁重的工作委托给后台工作,
  2. 以某种方式使客户端知道工作何时完成(此处有两个选项)。

实用(以上理论在Rails应用程序中的应用):

  1. 后台作业:Rails社区提供了各种各样的gem(+内置解决方案ActiveJob)来执行异步作业(=后台任务)。它们可以分为2个主要类别:

    • 持久状态:DelayedJobQue等(保持文件系统上的队列,如果服务器重新启动则可以恢复队列)
    • 内存中状态:ResqueSidekiq等(通常更快,但是如果服务器重新启动,则会丢失队列)
  2. 面向客户端: 这里有两个主要选项:

    • 轮询:客户端每隔X秒调用AJAX后端一次,以检查后台作业是否完成
    • 通过Web套接字
    • 订阅:客户端通过Web套接字连接到服务器,并侦听作业完成时触发的事件(例如:@Vasilisa指出的ActionCable)

基于意见的

如果要保持简单,我将采用一个非常简单的实现:Resque用于后端,而轮询系统用于前端。

如果您希望完成某些事情,能够抵抗服务器重新启动并恢复崩溃前的状态,则可以使用持久化版本(例如DelayedJob),也可以使用自己的内存解决方案持久的逻辑。