ruby-on-rails - RnR : Long running query, Heroku 超时 : webhooks? Ajax?

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

问题来了,我们有一个用户想要显示的数据。查询,我们优化和索引到我认为的一样快。我们可能会减少一两秒,但考虑到数据量,我们无能为力。

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

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

我们有点受到攻击,用户不满意,所以我们需要一个快速简单的解决方案。在此先感谢您的帮助!

最佳答案

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

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

我能够通过使用 Sinatra 的流式 API 来解决这个问题。如上所述,您可以通过在 30 秒时间结束之前在响应中发送至少一个 by 来“重置”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

这对我来说效果很好,因为“第一个字节的时间”(即数据库查询返回第一行所花费的时间远低于 30 秒的限制。

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

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

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

希望这对您有所帮助。

关于ruby-on-rails - RnR : Long running query, Heroku 超时 : webhooks? Ajax?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13272004/

相关文章:

mysql - Rails Search 3.2 返回所有查询而不是特定查询

ruby-on-rails - erb是什么意思?

ruby-on-rails - Brakeman 警告动态渲染路径

php - 使用AJAX调用PHP页面问题

ruby-on-rails - Ember-data、hasMany 关系、加载子集合、嵌套路由

ruby-on-rails - 在 Rails 应用程序中使用模块建模

javascript - Angular 和 SEO - 创建静态 HTML 版本

javascript - 是否有任何 json Rest 服务允许 javascript webapp 获取当前 UTC 时间?

ruby-on-rails-3 - 升级到 RSpec 2 : errors replaced with have(n). errors_on?需要解决方法

ruby-on-rails - 进入 2013 年,我应该选择 Dragonfly、Paperclip 还是 Carrierwave?