RnR:长时间运行的查询,Heroku超时:webhooks?阿贾克斯?

时间:2012-11-07 14:43:39

标签: ruby-on-rails ajax ruby-on-rails-3 webhooks

所以这就是问题,我们有一个用户想要显示的数据。查询,我们优化和索引的速度与我认为的速度一样快。我们可能会削减一两秒,但是有了大量的数据,我们无能为力。

无论如何,因此查询在限制为一天或两天的数据时运行良好,但是用户正在运行一周或两周的数据。因此,对两周或三周数据的查询大约需要40秒,Heroku超时为30秒,这不起作用。所以我们需要一个解决方案

所以在这里搜索和谷歌,我看到webhooks或Ajax作为解决方案工作的评论。但是,我一直无法找到一个真实的具体例子。我还看到一个评论,有人说我们可以发送一些“重置时钟”的响应。但同样听起来很有趣,但找不到一个例子。

我们处于枪口之下,用户不满意,所以我们需要快速而简单的解决方案。在此先感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

我遇到了类似的问题。我的Sinatra应用程序中实际上是一个“批量下载”页面,我的客户端应用程序调用该页面将数据导入浏览器中的本地webSQL数据库。

下载页面(让我们称之为“GET / download”)查询CouchDB数据库以获取给定视图中的所有文档,并且这部分过程(很像您的查询)需要很长时间。

我能够通过使用Sinatra的流API来解决这个问题。如上所述,您可以通过在30秒时间到来之前在响应中发送至少一个来“重置”Heroku中的时钟。这会将时钟重置为另外55秒(并且您发送的每个附加字节会再次重置时钟),这样当您仍在发送数据时,连接可以无限期地保持打开状态。

在Sinatra,我能够取代它:

get '/download' do
  body = db.view 'data/all'
end

..有这样的事情:

get '/download' do
  # stream is a Sinatra helper that effectively does 'chunked transfer encoding'
  stream do |out|
    # Long query starts here
    db.view 'data/all' do |row|
      # As each row comes back from the db, stream it to the front-end
      out << row
    end
  end
end

这对我很有用,因为'到第一个字节的时间'(即db查询返回第一行所用的时间远低于30s限制。

唯一的缺点是之前我将所有结果从数据库返回到我的Sinatra应用程序,然后计算整个结果的MD5总和以用作etag标头。我的客户端应用程序可以使用它来执行条件HTTP get(即,如果它尝试再次下载并且没有数据被修改,我可以发送302 Not Modified);加上它可以与它自己收到的数据的校验和进行比较(以确保它在传输过程中没有被破坏/修改)。

一旦开始在响应中传输数据流,您就无法计算要作为HTTP标头发送的内容的MD5总和(因为您还没有所有数据;并且您无法发送标头在你开始发送正文内容之后)。

我正在考虑将其更改为某种分页的多AJAX调用解决方案;正如Zenph上面提到的那样。那,或者使用某种工作进程(例如Resque,DelayedJob)来卸载查询;但是当我准备好提取数据时,我不确定如何通知客户端。

希望这有帮助。