2013-05-16 4 views
0

내가 Excel 파일, CSV 파일을 가져올 루 보석을 사용하고 있습니다를 사용할 때 루 오류 "파일이 존재하지 않습니다"레일 - 등 지연된 작업

코드가 작동 위대한)와 내 로컬 상자 또는 지체없는 직업없이, 그리고 b) 지체없이 일하는 Heroku에서. 불행히도 Heroku에서 실행하면 Delayed Job을 사용하면 실패합니다.

여기에 자세한 내용이 나와 있습니다.

는 컨트롤러 :

def importdo 
    fileimport = Fileimport.new 
    fileimport.file_name = params[:file].original_filename 
    fileimport.file_path = params[:file].path 
    fileimport.save 
    fileimportid = fileimport.id 
    Building.delay.import(fileimportid) 
    redirect_to buildings_path, notice: "Buildings import started . . . you will receive an email upon completion." 
end 

fileimport 내가 파일 이름과 파일 경로를 추적하는 데 사용하는 단지 테이블 (나는 PARAMS 이러한를 전달하는 시도했지만 YAML에 해시를 변환 할 때 DelayedJob 항상 문제가있는 것 그래서 대신 레코드 ID를 전달합니다.) 이것은 또한 내가 테이블에서 가져 오기를 추적하는 이점을 제공합니다. 같은

resources :buildings do 
    collection { post :importdo } 
end 

어쨌든 :

<% provide(:title, 'Import Buildings') %> 
<div class="row"> 
    <aside class="span4"> 
     <section> 
      <h1> 
       Import Products 
      </h1> 
      <%= form_tag importdo_buildings_path, multipart: true do %> 
       <%= file_field_tag :file %> 
       <%= submit_tag "Import" %> 
      <% end %> 
     </section> 
    </aside> 
</div> 

경로는 다음과 같습니다 : 여기

def self.import(fileimportid) 
    fileimport = Fileimport.find(fileimportid) 
    file_name = fileimport.file_name 
    file_path = fileimport.file_path 
    newcount = 0 
    updatecount = 0 
    updating = false 
    Building.acts_as_gmappable :process_geocoding => false 
    spreadsheet = open_spreadsheet(file_name, file_path) 
    header = spreadsheet.row(1) 
    (2..spreadsheet.last_row).each do |i| 
     row = Hash[[header, spreadsheet.row(i)].transpose] 

     if zip = row["zip"].to_i.to_s 
      if zip.length > 5 
       zip = zip.first(5) 
      end 
     else 
      raise "zip not valid" 
     end 

     if building = find_by_address_and_zip(row["address"], zip) 
      updating = true 
     else 
      building = Building.new 
     end 
     #building.name = row["name"] 
     building.zip = zip 
     building.address = row["address"] 
     building.city = row["city"] 
     building.save! 
     if updating 
      updatecount += 1 
     else 
      newcount += 1 
     end 
     updating=false 
    end 
    Building.acts_as_gmappable :process_geocoding => true 

    subject = "Your Building Import Completed Successfully!" 
    body = "Your Building Import completed successfully!\n\n" + newcount.to_s + " buildings were created.\n" + updatecount.to_s + " buildings were updated." 

    require 'rest_client' 

    RestClient.post MAILGUN_API_URL+"/messages", :from => "obfuscated", :to => "obfuscated", :subject => subject, :text => body 

end 

def self.open_spreadsheet(file_name, file_path) 
    case File.extname(file_name) 
     when ".csv" then Roo::Csv.new(file_path, nil, :ignore) 
     when ".xls" then Roo::Excel.new(file_path, nil, :ignore) 
     when ".xlsx" then Roo::Excelx.new(file_path, nil, :ignore) 
    else 
     raise "Unknown file type: #{file_name}" 
    end 
end 

파일 입력에 대한 내 양식입니다 : 여기

내 수입 클래스 방법 내가 말했듯이, 내 상자에서 (둘 다 지연된 직업없이) 잘 작동합니다. 지연된 직업없이 Heroku에서만 작동합니다 (즉, 퇴장해야합니다.). 여기에 내가지고있어 특정 오류입니다 (오류가 나에게 이메일로 전송되어, 나는이 지연된 경우 작업 레코드를 저장 :: 확인하고 만약 Last_Error를 확인하기 위해 관찰자 사용) :

file /tmp/RackMultipart20130516-13-7li3o7 does not exist 
/app/vendor/bundle/ruby/1.9.1/gems/roo-1.11.2/lib/roo/excel.rb:26:in `block in initialize' 
/app/vendor/bundle/ruby/1.9.1/gems/roo-1.11.2/lib/roo/generic_spreadsheet.rb:579:in `block in make_tmpdir' 
/app/vendor/ruby-1.9.3/lib/ruby/1.9.1/tmpdir.rb:83:in `mktmpdir' 
/app/vendor/bundle/ruby/1.9.1/gems/roo-1.11.2/lib/roo/generic_spreadsheet.rb:578:in `make_tmpdir' 
/app/vendor/bundle/ruby/1.9.1/gems/roo-1.11.2/lib/roo/excel.rb:19:in `initialize' 
/app/app/models/building.rb:84:in `new' 
/app/app/models/building.rb:84:in `open_spreadsheet' 
/app/app/models/building.rb:39:in `import' 

내 최초의 생각이이었다 그냥 Heroku 파일 시스템 건,하지만 난 그게 아니라 delayed_job 작동하지 않을 것이라고 생각합니다. 내 다른 생각은 비동기 어쩌면 그것은 타이밍 문제 (어쩌면 임시 파일 중 하나가 아직 없거나 거기에 더 이상 없다) 때문입니다.

모든 아이디어를 매우 높이 평가합니다.

+0

을 S3와 carrierwave을 사용 - 나는 확인했다 작업자가 회전하여 작업을 지연 시켰습니다. 지연 작업 작업을 처리하기 위해 다이노스를 회전 시켰습니까? – jbnunn

+0

나는 무의미한 작업을하고 있습니다. DelayedJob이 실행 중이므로 그 작업이 오류를 일으키고 있습니다. 작업자 준비가 타이밍 경우입니다. – bcb

답변

0

귀하의 초기 아이디어가 정확했습니다. 귀하의 문제는 Heroku 파일 시스템입니다. 즉 읽기 전용 규칙!

파일을 Heroku에 보내면 임시 폴더에 저장되며이 요청 동안에 만 사용할 수 있습니다. 한 요청 중에 작업을하고 파일을 사용할 수 있기 때문에 delayed_job없이 작동합니다.

그러나 지연된 작업은 요청이 끝나고 파일이 삭제되면 별도로 수행됩니다. .

가장 간단한 해결 방법은 몇 가지 클라우드 스토리지에 파일을 배치하는 것입니다 (난 내가 Heroku가에 DJ를 사용하지 않은,하지만 난 Resque을 사용하고 그 목적을 위해

관련 문제