【问题标题】:Rails callback after response is sent?发送响应后的Rails回调?
【发布时间】:2014-10-07 12:55:49
【问题描述】:

我有兴趣仅在将页面刷新到客户端之后在 Rails 中运行一些服务器端代码(类似于问题asked here for Django)。可以说,我正在寻找的是与 Rails 的 Django's request_finished signal 等效的功能。

我发现了对 ActiveRecord 的回调支持(它作用于数据库的持久性,而不是请求状态),以及用于推迟旨在允许页面响应完成的长时间运行任务的工具(但不费吹灰之力不支持仅在页面刷新到客户端后才启动该任务)。

[直接用例是处理用户请求的操作,这可能会中断正在运行的服务;目标是在继续进行破坏性操作之前将当前页面发送给客户端,而不会出现任何像硬编码延迟那样容易竞争且通常很麻烦的东西。

我想要完成的事情可能吗?我的目标是 Rails 4.x。

【问题讨论】:

  • 我不确定我是否在用例中有所区别,为什么延迟工作之类的东西不起作用?
  • 你可以依赖javascript吗? DOM 完成加载后应该很容易触发 ajax 请求
  • 您可以使用后台工作者或线程。没有理由尴尬地挂在刷新后事件中。
  • @DaveNewton,延迟工作的问题在于它是一个任意延迟——意味着你要么延迟太多,要么冒着延迟不够的风险(尤其是例如,处理请求的线程在调试器中暂停),而不是有一个触发器或回调,它会尽快而不是之前。

标签: ruby-on-rails


【解决方案1】:

如果你可以使用 Javascript,那么你可以这样做:

function pageLoadCallback(){
    $.ajax({ 
        // tell server to do something now that the page is loaded
    })    
}

$(document).ready(function(){
    pageLoadCallback();
});

【讨论】:

  • facepalm。我真的应该想到这一点。
  • 这是否是正确的方法,这是对“Rails 回调”的回答吗?
【解决方案2】:

看看https://github.com/celluloid/celluloid 了解你想要做的事情的一些起点,基本上(据我所知)你有一个需要很长时间才能排队的任务,你想要那个推迟到您完成对客户的请求之后..

两种常见的方法:

  1. Thread.new { HeavyWeightTask.new.enqueue } - (简单由很多线程生死)
  2. 或者任务类中的include Celluloid,然后调用HeavyWeightTask.new.async.enqueue(也很简单,但是使用了线程池)

【讨论】:

  • 实际上,任务不会花费很长时间——我可以阻止服务器在执行期间响应其他请求,这样就很好了。但是,在将请求刷新到客户端之前,它们不得执行,而且我不确定这里提到的任何一种方法是否满足该要求。
  • 我相信提供的两个示例都实现了允许请求/响应周期完成并关闭与服务器的连接的目标。然后工作将在新线程 (1) 或线程池的成员 (2) 上开始
  • 这并没有回答仅在发送响应后才执行某些任务的问题。它还使用了查尔斯表示他已经知道并且不适合他的申请的方法。它可能会达到类似的目标,但查尔斯在他的问题中明确表示他已经考虑并放弃了这种解决方案。
  • @nort -- 如被问及,这是目标的明确部分仅在响应完全刷新到客户端后才开始,因为如果正在运行操作 - - 这可能会中断服务器操作 - 在此之前开始,可能无法完整接收该响应。这就是为什么任何具有任意延迟的方法都是一个坏主意的原因——要么它太长并且在用户期望的时候动作没有运行,要么它太短而无法处理不寻常的情况(比如 paused-in-a -调试器场景)。
猜你喜欢
  • 1970-01-01
  • 2020-10-21
  • 2023-04-03
  • 1970-01-01
  • 2021-12-25
  • 2015-06-01
  • 2015-10-20
  • 1970-01-01
  • 2017-06-26
相关资源
最近更新 更多