2011-12-12 57 views
5

我需要關於使用heroku,回形針,延遲作業以及必要時s3上傳和延遲處理文件的設計反饋。部分內容已在其他地方進行過討論,但我無法在任何地方找到完整的討論。回形針,延遲作業,S3,Heroku - 延遲處理敏感上傳文件的設計:db或s3?

任務描述:

  1. 上傳文件(使用回形針至S3在Heroku /分貝)。文件需要保密,因爲它包含敏感數據。用於處理
  2. 隊列文件(延遲作業)
  3. 工作獲取隊列運行
  4. 文件被檢索(從S3 /分貝),並且處理完成
  5. 文件被刪除(從S3 /分貝)

由於我使用的是延遲作業,因此我必須決定是將文件存儲在數據庫中還是存儲在s3上。我假設將文件存儲在Web服務器上是不可能的,因爲我正在使用heroku並推遲了工作。上傳文件到s3需要很長時間。但是,以db存儲文件更加昂貴。理想情況下,我們希望處理儘快完成。

什麼是更常見的設計模式?將文件存儲在s3上?存儲文件在db?用於檢索和處理存儲在s3中的文件的任何特定建議的寶石(aws-s3?s3?)?

回答

4

Heroku在任何服務器請求上都有30秒的超時時間(學習困難),所以肯定存儲s3上的文件是必須的。

嘗試carrierwavecarrierwave railscasts),而不是回形針,因爲我更喜歡加入傭工而來板載,再加上有一些偉大的插件,如carrierwave_direct上傳大文件到S3,這與carrierwave很好地集成。

Delayed_job(railscasts - delayed_job)將很好地用於從s3中刪除文件以及可能需要的任何其他後臺處理。

我的寶石文件包括以下內容:

gem 'delayed_job' 

gem "aws-s3", :require => 'aws/s3' 

gem 'fog' 

gem 'carrierwave' 

gem 'carrierwave_direct' 

霧寶石是在一個地方的所有帳戶信息的好方法,並設置了一切相當不錯。對於AWS寶石how-to,很好的資源。

這裏有一個例子控制器提交表單時上傳(有這樣做的肯定是更好的方法,但用於說明目的)

def create 
    @asset = Asset.new(:description => params[:description], :user_id => session[:id], :question_id => @question.id) 
    if @asset.save && @asset.update_attributes(:file_name => sanitize_filename(params[:uploadfile].original_filename, @asset.id)) 
     AWS::S3::S3Object.store(sanitize_filename(params[:uploadfile].original_filename, @asset.id), params[:uploadfile].read, 'bucket_name', :access => :private, :content_type => params[:uploadfile].content_type) 
      if object.content_length.to_i < @question.emailatt.to_i.megabytes && object.content_length.to_i < 5.megabytes 
       url = AWS::S3::S3Object.url_for(sanitize_filename(params[:uploadfile].original_filename, @asset.id), 'bucket_name') 
       if @asset.update_attributes(:download_link => 1) 
        if Usermailer.delay({:run_at => 5.minutes.from_now}).attachment_user_mailer_download_notification(@asset, @question) 
         process_attachment_user_mailer_download(params[:uploadfile], @asset.id, 24.hours.from_now, @question.id) 
         flash[:notice] = "Thank you for the upload, we will notify this posts author" 
        end 
       end 
      end 
    else 
     @asset.destroy 
     flash[:notice] = "There was an error in processing your upload, please try again" 
     redirect_to(:controller => "questions", :action => "show", :id => @question.id) 
    end 
end 


private 

    def sanitize_filename(file_name, id) 
     just_filename = File.basename(file_name) 
     just_filename.sub(/[^\w\.\-]/,'_') 
     new_id = id.to_s 
     new_filename = "#{new_id}" + just_filename 
    end 

    def delete_process(uploadfile, asset_id, time, question_id) 
     asset = Asset.find(:first, :conditions => ["id = ?", asset_id]) 
     if delete_file(uploadfile, asset_id, time) && asset.destroy 
      redirect_to(:controller => "questions", :action => "show", :id => question_id) 
     end 
    end 


def process_attachment_user_mailer_download(uploadfile, asset_id, time, question_id) 
     asset = Asset.find(:first, :conditions => ["id = ?", asset_id]) 
     if delete_file(uploadfile, asset_id, time) && @asset.delay({:run_at => time}).update_attributes(:download_link => 0) 
      redirect_to(:controller => "questions", :action => "show", :id => question_id) 
     end 
    end 

    #S3 METHODS FOR CREATE ACTION 

    #deletes the uploaded file from s3 
    def delete_file(uploadfile, asset_id, time) 
     AWS::S3::S3Object.delay({:run_at => time}).delete(sanitize_filename(uploadfile.original_filename, asset_id), 'bucket_name') 
    end 

很多不必要的代碼,我知道(當我寫這篇從Rails開始)。希望它能給出一些關於編寫這種類型的應用程序的過程的一些想法。希望能幫助到你。

3

就我個人而言,我使用:

  • Delayed Job
  • Paperclip
  • Delayed Paperclip其上傳S3的原始文件 並創建自定義的後處理延遲的工作。它 可以添加一個列給你的模型,說明該文件正在處理 。

只有幾行設置。你可以用回形針插值和生成器做很多事情。