首页 > 解决方案 > Rails:我可以从工作中重定向吗?

问题描述

用户向控制器发起 POST 请求,这会导致更长的操作流程,这些操作是网络绑定的,通常需要 2-3 秒才能完成。之后,用户被重定向到新页面以接收结果。

据我了解,Rails 中同时可能的连接数与控制器内阻塞的请求数直接相关。因此,最好将此操作作为作业排入队列,并在作业完成后从那里进行重定向。

这将使轻松支持更多的同时连接成为可能,因为可以卸载这些作业的处理。

在 Rails 中是否有可能做到这一点?或者,如何扩展网络绑定请求以支持多个同时连接?并且请:我不希望客户端进行轮询,这不适合像 RoR 这样的现代 Web 框架。

标签: ruby-on-railsmultithreadingnetworkingconnection-poolingrails-activejob

解决方案


轮询的另一种方法是使用 ActionCable,在客户端加载包含大量请求的页面后,例如结帐表单,您的 js 将根据用户会话 + 任务名称自动建立具有特定通道 id 的 action-cable 通道,例如:繁重的任务:123xyz

现在,当用户提交繁重的任务时,验证后的控制器将委托给一个作业(带有通道 id heavy-task:123xyz),因此该控制器将自由地接受另一个请求。过了一会儿,工作完成了,这将使用 AcionCable 将结果广播到频道heavy-task:123xyz

客户端从频道收到作业消息后,将立即重定向到结果页面。

client1 ---- get/ load page -------> server 
    |   <------------------------200 controller
    |                                   |
establish action-cable <---------------------> Channel
    |                                   |        |
request -- post/ heavy task ------>  controller  | 
                                        |----------enqueue job --> sidekiq---
                                        |        |                          | 
                                        |        |<--------------------job done
                                        |        |
client1 <----------------------------------------- broadcast
    |                                   |        X close Channel
    ------ redirect_to get/other -----------> another-controller
                                        |           |

笔记:

  • 通道应该在到达表单页面后尽快建立的原因可能在建立过程完成之前完成(因此客户端不会收到作业消息)
  • 发送作业结果消息后应立即关闭通道,因为通道占用大量资源(内存)
  • 不确定规模,因为如果有这么多频道,性能会下降,你可以考虑anycable参考

推荐阅读