【问题标题】:Writing temp files to Heroku from an S3 hosted file从 S3 托管文件将临时文件写入 Heroku
【发布时间】:2015-10-11 22:43:28
【问题描述】:

我有一个托管在 Heroku 上的 rails 应用程序。情况如下:用户应该能够使用 s3 将 PDF(Batch 的一个实例)上传到我们的应用程序;用户还应该能够获取上传 PDF 的 s3 网址,并使用HyPDF 通过指定文件路径和要拆分的所需页面(以创建 Essay 实例)将其拆分为更多 PDF。

所有这些都发生在对/essays 的同一个 POST 请求中。

这是我今天一直在使用的代码:

 def create
    if params[:essay].class == String 
      batch_id = params[:batch_id].gsub(/[^\d]/, '').to_i
      break_up_batch(params, batch_id)
      redirect_to Batch.find(batch_id), notice: 'Essays were successfully created.'
    else 
      @essay = Essay.new(essay_params)
      respond_to do |format|
        if @essay.save
          format.html { redirect_to @essay, notice: 'Essay was successfully created.' }
          format.json { render :show, status: :created, location: @essay }
        else
          format.html { render :new }
          format.json { render json: @essay.errors, status: :unprocessable_entity }
        end
      end
    end
 end

# this is a private method
def break_up_batch(params, batch_id)
  essay_data = []
  # create a seperate essay for each grouped essay
  local_batch = File.open(Rails.root.join('tmp').to_s + "temppdf.pdf" , 'wb') do |f|
    f.binmode
    f.write HTTParty.get(Batch.find(batch_id).document.url).parsed_response
    f.path
  end

  params["essay"].split("~").each do |data|
    data = data.split(" ")
    hypdf_url = HyPDF.pdfextract(
        local_batch,
        first_page: data[1].to_i, 
        last_page: data[2].to_i,
        bucket: 'essay101',
        public: true

    )
      object = {student_name: data[0], batch_id: batch_id, url: hypdf_url[:url]}
      essay_data << object 
  end

  essay_data.each {|essay| Essay.create(essay)}
  File.delete(local_batch) 
end

我无法让文件显示在 Heroku 上,我正在检查 heroku run bashls tmp。所以当方法运行时,一个空白文件被上传到 S3。我写了一些 jQuery 来填充一个隐藏字段,这就是为什么在代码中间有时髦的分裂。

【问题讨论】:

  • Heroku 工具带命令 heroku run bash 会为您的应用程序创建一个新部署,因此您不会看到通过您的 rails 应用程序创建的任何文件。 Heroku 应用程序之间不共享文件空间,因此建议使用 S3 存储桶。

标签: ruby-on-rails heroku amazon-s3 temporary-files


【解决方案1】:

由于 Heroku 的临时文件系统,我强烈建议尽快将该文件从您的文件系统中删除。也许使用以下内容:

  1. 用户上传到 S3(最好直接:https://devcenter.heroku.com/articles/direct-to-s3-image-uploads-in-rails
  2. 启动后台工作程序以获取文件并在内存中进行必要的处理
  3. 如果在正确处理文件时需要通知用户,请在数据库中设置“状态”字段并允许前端应用程序轮询 Web 服务器以获取更新。向用户显示“处理中”,直到后台工作人员更改其状态。

此方法还允许您的 Web 进程快速响应,而不会占用资源,也不会触发 H12(请求超时)错误。

【讨论】:

    【解决方案2】:

    原来使用File 类并不是正确的方法。但是使用Tempfile 可以!

    def break_up_batch(params, batch_id, current_user)
          essay_data = []
          # create a seperate essay for each grouped essay
          tempfile = Tempfile.new(['temppdf', '.pdf'], Rails.root.join('tmp'))
          tempfile.binmode
          tempfile.write HTTParty.get(Batch.find(batch_id).document.url).parsed_response
          tempfile.close
          save_path = tempfile.path
    
          params["essay"].split("~").each do |data|
            data = data.split(" ")
            hypdf_url = HyPDF.pdfextract(
                save_path,
                first_page: data[1].to_i, 
                last_page: data[2].to_i,
                bucket: 'essay101',
                public: true
    
            )
              object = {student_name: data[0], batch_id: batch_id, url: hypdf_url[:url]}
              essay_data << object 
          end
          essay_data.each do |essay| 
            saved_essay = Essay.create(essay)
            saved_essay.update_attributes(:company_id => current_user.company_id) if current_user.company_id
          end
          tempfile.unlink
        end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-06
      • 1970-01-01
      • 2012-10-27
      • 2013-02-02
      • 2010-11-10
      • 2023-03-10
      相关资源
      最近更新 更多