首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在heroku上流式传输响应rails应用程序

如何在heroku上流式传输响应rails应用程序
EN

Stack Overflow用户
提问于 2012-12-14 04:03:44
回答 2查看 1K关注 0票数 2

我有一个在heroku上运行的rails 3.1应用程序。我需要为用户提供下载csv数据的能力。我正在尝试流式传输数据,但它们都是一次性发送的。这对于较大的请求将超时。

heroku网站上有很多关于流媒体和分块的讨论,但据我所知,thin收集所有数据并一次性发送。我怎么才能让它工作?

我需要添加一些中间件吗?例如,独角兽的代码流可以很好地运行在混血中。

EN

回答 2

Stack Overflow用户

发布于 2012-12-14 04:13:51

我很确定你只需要添加

代码语言:javascript
运行
复制
stream

添加到控制器的顶部。

有关HTTP streaming的更多信息,请访问RailsCasts:http://railscasts.com/episodes/266-http-streaming

票数 0
EN

Stack Overflow用户

发布于 2021-08-08 21:16:27

这个问题真的很老了,但是这个问题仍然很常见,因为Heroku的响应有30英尺的限制,所以我将添加一些代码来说明我是如何实现这个问题的。在带有Puma服务器的Heroku上使用Rails 5.2和6.1。

我使用的是#send_stream方法(只出现在edge rails中,未来的rails 7中才会出现),所以我只是复制了它并手动设置了Last-Modified标头。添加了all in a rails关注点以重用它。

代码语言:javascript
运行
复制
module Streameable
  extend ActiveSupport::Concern
  include ActionController::Live

  def send_stream(filename:, disposition: 'attachment', type: nil)
    response.headers['Content-Type'] =
      (type.is_a?(Symbol) ? Mime[type].to_s : type) ||
      Mime::Type.lookup_by_extension(File.extname(filename).downcase.delete('.')) ||
      'application/octet-stream'

    response.headers['Content-Disposition'] =
      ActionDispatch::Http::ContentDisposition.format(disposition: disposition, filename: filename)  # for Rails 5, use content_disposition gem

    # extra: needed for streaming correctly
    response.headers['Last-Modified'] = Time.now.httpdate

    yield response.stream
  ensure
    response.stream.close
  end
end

class ExporterController < ApplicationController
  include Streameable

  def index
    respond_to do |format|
      format.html # index.html
      format.js   # index.js
      format.csv do
        send_stream(attachment_opts) do |stream|
          stream.write "email_address,updated_at\n"

          50.times.each do |i|
            line = "user_#{i}@acme.com,#{Time.zone.now}\n"
            stream.write line
            puts line
            sleep 1  # force slow response for testing respose > 30''
          end
        end
      end
    end
  end

  private

  def attachment_opts
    {
      filename: "data_#{Time.zone.now.to_i}.csv",
      disposition: 'attachment',
      type: 'text/csv'
    }
  end
end

然后,如果您使用curl之类的命令,您将看到每秒生成的输出。

代码语言:javascript
运行
复制
$ curl -i  http://localhost:3000/exporter.csv 

重要的一点是,通过使用Enumerable模块编写代码来使用#each迭代数据。哦,关于ActiveRecord的小贴士,使用#find_each,这样DB fetch就是批处理的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13867547

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档