简体   繁体   English

Rails:使用fog和resque将文件上传到AS3

[英]Rails: Uploading a file to AS3 using fog and resque

The Problem: 问题:

I have a rails app that requires a user to upload some type of spreadsheet (csv, xslx, xsl etc) for processing which can be a costly operation so we've decided to send it off to a background service as a solution to this problem. 我有一个Rails应用程序,要求用户上传某种类型的电子表格(csv,xslx,xsl等)进行处理,这可能是一项昂贵的操作,因此,我们决定将其发送到后台服务作为此问题的解决方案。 The issue we're concerned about is that because our production system is on Heroku we need to store the file on AS3 first then retrieve later for processing. 我们担心的问题是,因为我们的生产系统位于Heroku上,所以我们需要先将文件存储在AS3上,然后再检索以进行处理。

Because uploading the file to AS3 is in itself a costly operation, this should probably also be done as a background job. 由于将文件上传到AS3本身是一项昂贵的操作,因此也可能应将其作为后台作业来完成。 The problem is the concern that using Resque to do this could eat up a lot of RAM due to Resque needing to put the file data into Redis or later retrieval. 问题在于,由于Resque需要将文件数据放入Redis或稍后进行检索,因此使用Resque这样做可能会占用大量RAM。 As you know, Redis only stores its data in RAM and also prefers simple key value pairs so we would like to try and avoid this. 如您所知,Redis仅将其数据存储在RAM中,并且更喜欢简单的键值对,因此我们希望尝试避免这种情况。

Heres some pseudocode as an example of what we'd like try and do: 以下是一些伪代码,作为我们想要尝试的示例:

workers/AS3Uploader.rb 工人/AS3Uploader.rb

require 'fog'

class AS3Uploader
  @queue = :as3_uploader
  def self.perform(some, file, data)
    # create a connection
    connection = Fog::Storage.new({
      :provider                 => 'AWS',
      :aws_access_key_id        => APP_CONFIG['s3_key'],
      :aws_secret_access_key    => APP_CONFIG['s3_secret']
    })

    # First, a place to contain the glorious details
    directory = connection.directories.create(
      :key    => "catalog-#{Time.now.to_i}", # globally unique name
      :public => true
    )

    # list directories
    p connection.directories

    # upload that catalog
    file = directory.files.create(
      :key    => 'catalog.xml',
      :body   => File.open(blah), # not sure how to get file data here with out putting it into RAM first using Resque/Redis
      :public => true
  end

  # make a call to Enqueue the processing of the catalog
  Resque.enqueue(CatalogProcessor, some, parameters, here)
end

controllers/catalog_upload_controller.rb 控制器/catalog_upload_controller.rb

def create
  # process params

  # call Enqueue to start the file processing
  # What do I do here? I could send all of the file data here right now
  # but like I said previously that means storing potentially 100s of MB into RAM
  Resque.enqueue(AS3Uploader, some, parameters, here)
end

The way I would suggest you to do would be 我建议你做的方式是

  • store your file in tmp dir you create and get the file-path 将您的文件存储在您创建的tmp dir中并获取file-path
  • tell Resque to upload the file by using the file-path 告诉Resque使用file-path上传文件
  • make Resque to store the file-path in the redis not the whole file-content ( It would be very expensive ) 使Resquefile-path存储在redis而不是整个file-content (这将非常昂贵)
  • Now worker will upload the file to AWS- S3 现在工作人员会将文件上传到AWS- S3

Note: If you have multiple instances like One instance for background processing, One for database, One as utility instance then your tmp dir may not be available to other instances.. so store the file in the temp dir inside the instance holding the resque 注意:如果您有多个实例,例如一个实例用于后台处理,一个实例用于数据库,一个实例作为实用程序实例,则您的tmp目录可能无法用于其他实例..因此,请将文件存储在保存有resque的实例的temp目录中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM