9

我一直在研究使用 EventMachine 支持一些工作的可能性。在 Sinatra 中,这似乎工作得很好,但 Rails 3 似乎在渲染视图之前执行所有滴答声。

当我在瘦网络服务器下运行以下代码时,它的行为符合预期。第一个请求立即返回,第二个请求正在等待 3 秒的睡眠调用完成。这是预期的行为。

class EMSinatra < Sinatra::Base
  get "/" do
    EM.next_tick { sleep 3 }
    "Hello"
  end
end

而在 Rails 3 运行中,我正在尝试做同样的事情:(在瘦身下运行)

class EmController < ApplicationController
  def index
    EM.next_tick {
      sleep(3)
    }
  end
end

在 Rails 中,睡眠调用发生在将视图呈现给浏览器之前。结果是我等待 3 秒来渲染初始页面。

有谁知道为什么会这样?我不是在寻找关于这是否是一个好习惯的评论。我只是在做实验。将小任务投入反应器循环似乎是一件有趣的事情。如果我要发出一些非阻塞的 http 请求,为什么客户端必须等待?

4

2 回答 2

3

我不确定这是您正在寻找的答案,但我之前对此进行了一些研究。让我告诉你一点背景信息:我们想要实现的是,即使控制器动作需要很长时间才能加载,rails 已经刷新了模板树的部分(例如布局的第一部分)。这样做的效果是,当网络服务器仍在工作时,用户已经在他们的浏览器中看到了一些东西。当然,主视图必须等待渲染,因为它可能需要来自控制器操作的数据。

这种技术也被称为 BigPipe,facebook 写了一篇关于这个的不错的博客:http: //www.facebook.com/notes/facebook-engineering/bigpipe-pipelining-web-pages-for-high-performance/389414033919

无论如何,在为 rails 3 进行了一些研究以实现这一目标之后,我发现了 Yehuda Katz 的这篇博文。 http://yehudakatz.com/2010/09/07/automatic-flushing-the-rails-3-1-plan/

所以现在我认为你真的必须坚持等待控制器

于 2011-02-23T10:52:45.400 回答
0

使用 EM.defer 而不是 EM.next_tick 会导致在发送回响应后发生睡眠。

于 2012-10-06T05:20:44.173 回答