2012-12-29 48 views
0

具有以下,長期運行耙批:無法趕上紅寶石例外

class SyncStarredRepo 
    include Mongoid::Document 

    def self.update 

    User.all.map do |user| 

     if user.email != "[email protected]" 
     begin 
      conn = Faraday.new "https://api.github.com" 
      i = 1 
      begin 
      resp = conn.get "https://stackoverflow.com/users/#{user.nickname}/starred?page=#{i}" 
      resp.body.each do |repo| 
       attempts = 0 
       begin 
       existing_repo = user.watchlists.where(html_url: "#{repo['html_url']}").batch_size(30) 
       if existing_repo.exists? 
        existing_repo.first.update_attributes!(
         html_url: "#{repo['html_url']}", 
         description: "#{repo['description']}" 
       ) 
       else 
        user.watchlists.create!(
         html_url: "#{repo['html_url']}", 
         description: "#{repo['description']}" 
       ) 
       end 

       rescue Moped::Errors::CursorNotFound => c 
       attempts += 1 
       puts "error message: #{c.message}" 
       if attempts < 3 
        puts "Retrying... Attempt #: #{attempts.to_s}" 
        sleep(3) 
        retry 
       else 
        puts "already retried 3 times, go to the next" 
        next 
       end 
       end 

      end 
      i += 1 
      end until resp.body.empty? 

     rescue TypeError => e 
      puts "message error (e.inspect): #{e.inspect}" 
      puts "go to the next user" 
      next  
     rescue 
      p $!, *[email protected] 
      next  
     end 
     end 

    end 
    end 
end 

我aspected趕上助力車::錯誤:: CursorNotFound例外,但它不工作。

在crontab登錄我剛剛得到這個消息:

rake aborted! 
The operation: "GET MORE" 
failed with error "cursor 2509315744412059250 not found" 

則批處理將停止並退出,而我是aspecting救援消息和下一個循環操作。

UPDATE

我想 「擴展」 開捕例外設置爲StandardError的,這樣做:

 rescue 
     p $!, *[email protected] 
     next 
     end 

...以防萬一,即使CursorNotFound繼承自MongoError,它繼承自StandardError,如你所見here

UPDATE

我剛剛更新了以前簡單的代碼,通過耙使用完整SyncStarredRepo類,以防萬一我失去了一些東西進入循環邏輯,開始/救援/末等。 ..

UPDATE

遵循棧跟蹤由rake -t印刷:

rake aborted! 
The operation: "GET MORE" 
failed with error "cursor 5781947091640256877 not found" 
/var/www/gitwatcher/vendor/bundle/ruby/1.9.1/gems/moped-1.3.2/lib/moped/node.rb:210:in `get_more' 
/var/www/gitwatcher/vendor/bundle/ruby/1.9.1/gems/moped-1.3.2/lib/moped/cursor.rb:44:in `get_more' 
/var/www/gitwatcher/vendor/bundle/ruby/1.9.1/gems/moped-1.3.2/lib/moped/cursor.rb:29:in `each' 
/var/www/gitwatcher/vendor/bundle/ruby/1.9.1/gems/moped-1.3.2/lib/moped/query.rb:77:in `each' 
/var/www/gitwatcher/vendor/bundle/ruby/1.9.1/gems/moped-1.3.2/lib/moped/query.rb:77:in `each' 
/var/www/gitwatcher/vendor/bundle/ruby/1.9.1/bundler/gems/mongoid-92cad16e9fbf/lib/mongoid/contextual/mongo.rb:133:in `block in each' 
/var/www/gitwatcher/vendor/bundle/ruby/1.9.1/bundler/gems/mongoid-92cad16e9fbf/lib/mongoid/contextual/mongo.rb:605:in `selecting' 
/var/www/gitwatcher/vendor/bundle/ruby/1.9.1/bundler/gems/mongoid-92cad16e9fbf/lib/mongoid/contextual/mongo.rb:132:in `each' 
/var/www/gitwatcher/vendor/bundle/ruby/1.9.1/bundler/gems/mongoid-92cad16e9fbf/lib/mongoid/contextual.rb:18:in `each' 
/var/www/gitwatcher/app/models/sync_starred_repo.rb:15:in `map' 
/var/www/gitwatcher/app/models/sync_starred_repo.rb:15:in `update' 
/var/www/gitwatcher/lib/tasks/scheduler.rake:9:in `block in <top (required)>' 
/usr/local/rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/task.rb:205:in `call' 
/usr/local/rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/task.rb:205:in `block in execute' 
/usr/local/rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/task.rb:200:in `each' 
/usr/local/rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/task.rb:200:in `execute' 
/usr/local/rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/task.rb:158:in `block in invoke_with_call_chain' 
/usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/monitor.rb:211:in `mon_synchronize' 
/usr/local/rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/task.rb:151:in `invoke_with_call_chain' 
/usr/local/rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/task.rb:144:in `invoke' 
/usr/local/rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/application.rb:116:in `invoke_task' 
/usr/local/rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/application.rb:94:in `block (2 levels) in top_level' 
/usr/local/rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/application.rb:94:in `each' 
/usr/local/rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/application.rb:94:in `block in top_level' 
/usr/local/rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/application.rb:133:in `standard_exception_handling' 
/usr/local/rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/application.rb:88:in `top_level' 
/usr/local/rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/application.rb:66:in `block in run' 
/usr/local/rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/application.rb:133:in `standard_exception_handling' 
/usr/local/rvm/gems/[email protected]/gems/rake-0.9.2.2/lib/rake/application.rb:63:in `run' 
/usr/local/rvm/gems/[email protected]/gems/rake-0.9.2.2/bin/rake:33:in `<top (required)>' 
/usr/local/rvm/gems/[email protected]/bin/rake:23:in `load' 
/usr/local/rvm/gems/[email protected]/bin/rake:23:in `<main>' 
Tasks: TOP => update_starred_list_per_user 
+0

不是100%肯定,但可能是因爲異常是在第二個'begin'塊中引發的嗎?如果你將救援移動到內部'begin'塊內,會發生什麼? –

+0

我正在嘗試...但運行需要一個或多或少...我會盡快更新 –

+0

@freakyDaz這並不重要。如果沒有與'begin ... end'關聯的'rescue',那麼異常就會正常起泡。 –

回答

1

User.all.map期間出現錯誤,因此您必須將您的begin .. rescue塊封裝在整個語句中。

舊的答案基於初始信息:

你挽救你的循環之外,如此 retry不會做的正是你所期望的( next,另一方面會提高一個 SyntaxError(1.9)或者 LocalJumpError(1.8))。實際上, rescue內部的 retry只是導致 begin .. rescue塊內的代碼再次運行。

正確的代碼應該看起來像:

attempts = 0 
begin 
    i = 1 
    resp = conn.get "https://stackoverflow.com/users/#{user.nickname}/starred?page=#{i}" 
    resp.body.each do |repo| 
    begin 
     existing_repo = user.watchlists.where(html_url: "#{repo['html_url']}") 
     if existing_repo.exists? 
     existing_repo.first.update_attributes!(
      html_url: "#{repo['html_url']}", 
      description: "#{repo['description']}" 
     ) 
     else 
     user.watchlists.create!(
      html_url: "#{repo['html_url']}", 
      description: "#{repo['description']}" 
     ) 
     end 
    rescue Moped::Errors::CursorNotFound => c 
     attempts += 1 
     puts "error message: #{c.message}" 
     if attempts < 3 
     puts "Retrying... Attempt #: #{attempts.to_s}" 
     sleep(3) 
     retry 
     else 
     puts "already retried 3 times, go to the next" 
     next 
     end 
    end 
    end 
    i += 1 
end until resp.body.empty? 

+0

你是對的,圍繞User.all.map聲明它捕獲異常 –

0

雖然我沒有看過你的代碼仔細,請注意,裸rescue捕獲所有異常。爲此,您需要rescue Exception

+1

當然,我知道,但這不是一個好的做法(請參閱http://stackoverflow.com/questions/10048173/why-is-it-不好的樣式 - 營救例外 - e-in-ruby) –

+0

這取決於情況。有很多情況下,無論發生什麼,都可以捕捉所有異常。 –

+0

Ruby向所有線程發送一個爲SignalException的Interrupt類,以便當進程獲得INT/Ctrl-C信號時,所有線程將放開並且進程將關閉。如果你營救異常,你可能會發現這個異常並忽略它,使你的線程和進程成爲一個不可驅動的計算殭屍。你唯一的選擇就是把你的kill -9霰彈槍瞄準頭部。 –