2014-06-30 84 views
0

我試圖使用推客戶端的寶石從網站(近實時數據)接收推。但是,劇本往往會死去很多。搶救異常克服寶石錯誤?

如果我將Pusher數據發佈到我的屏幕上,那麼只要我關心讓它運行,客戶端就會運行。但是,如果我將Pusher數據保存到文件中,或者將數據傳遞給Gearman作業,使用gearman gem,或者使用dalli gem將數據存入Memcache,那麼我的客戶端腳本崩潰。

我的服務器沒有以任何方式超載。它有8個內核和24 GB的RAM。通常情況下,任何時候單個內核都不會達到100%,並且不會超過6個內存,並且不會超過12 GB的內存。

我當前的客戶端腳本化身試圖將數據傳遞給Gearman作業,我希望這會減輕數據的保存並防止Pusher提供的任何更新,這些更新通常可能會非常快。這是一個典型錯誤的腳本踢出:

ruby-2.1.1/gems/gearman-ruby-3.0.7/lib/gearman/taskset.rb:99:in `handle_job_created': Got unexpected job_created notification with handle H:hawk898 
     from /home/gabe/.rvm/gems/ruby-2.1.1/gems/gearman-ruby-3.0.7/lib/gearman/taskset.rb:222:in `read_packet' 
     from /home/gabe/.rvm/gems/ruby-2.1.1/gems/gearman-ruby-3.0.7/lib/gearman/taskset.rb:67:in `add_task_internal' 
     from /home/gabe/.rvm/gems/ruby-2.1.1/gems/gearman-ruby-3.0.7/lib/gearman/taskset.rb:29:in `add_task' 
     from /var/www/.../utils/pusher_utils.rb:81:in `send_to_gearman' 
     from /var/www/.../utils/pusher_utils.rb:10:in `export_to_gearman' 
     from /var/www/.../async_pusher.rb:59:in `block in <main>' 
     from /home/gabe/.rvm/gems/ruby-2.1.1/gems/pusher-client-0.4.0/lib/pusher-client/channel.rb:30:in `call' 
     from /home/gabe/.rvm/gems/ruby-2.1.1/gems/pusher-client-0.4.0/lib/pusher-client/channel.rb:30:in `block in dispatch' 
     from /home/gabe/.rvm/gems/ruby-2.1.1/gems/pusher-client-0.4.0/lib/pusher-client/channel.rb:29:in `each' 
     from /home/gabe/.rvm/gems/ruby-2.1.1/gems/pusher-client-0.4.0/lib/pusher-client/channel.rb:29:in `dispatch' 
     from /home/gabe/.rvm/gems/ruby-2.1.1/gems/pusher-client-0.4.0/lib/pusher-client/channel.rb:22:in `dispatch_with_all' 
     from /home/gabe/.rvm/gems/ruby-2.1.1/gems/pusher-client-0.4.0/lib/pusher-client/socket.rb:201:in `send_local_event' 
     from /home/gabe/.rvm/gems/ruby-2.1.1/gems/pusher-client-0.4.0/lib/pusher-client/socket.rb:73:in `block (2 levels) in connect' 
     from /home/gabe/.rvm/gems/ruby-2.1.1/gems/pusher-client-0.4.0/lib/pusher-client/socket.rb:67:in `loop' 
     from /home/gabe/.rvm/gems/ruby-2.1.1/gems/pusher-client-0.4.0/lib/pusher-client/socket.rb:67:in `block in connect' 

我不想深入到推動器客戶端的寶石,弄清爲什麼發生這種情況。我只想繼續前進,所以我很想用rescue Exception。我保存了Pusher提供的下游邏輯和操作數據。數據正在快速移動,我可以確定作業是否真的將它交給了Gearman,可能錯過了下一次更新或者延遲它,或者我可以簡單地將當前存儲的數據標記爲陳舊/無效,然後等待來自Pusher的下一次更新。我的首選是將其標記爲陳舊/無效並等待。

我讀過「Why is it a bad style to `rescue Exception => e` in Ruby?」,並知道rescue Exception是不好的做法。然而,我沒有這樣做來掩蓋我的代碼中的錯誤 - 我查看了在發生錯誤時傳遞給Gearman的工作負載,他們很好。

我運行:

Ubuntu 12.04 
RVM and Ruby 2.1.1 

這裏是發送心跳工作量到Gearman的作業服務器的一些示例代碼:

def heartbeat(site, marketId, taskset) 
    startTime = timeID() 

    workload = myhash() 
    workload['marketId'] = marketId 
    workload['site'] = site 
    workload['src'] = 'pusher' 
    workload['time'] = startTime 
    workload['staleTime'] = startTime + 1 

    send_to_gearman('update_heartbeat', json_encode(workload), taskset) 

    endTime = timeID() 
    delta =endTime - startTime 
    puts sprintf("Heartbeat Task Handoff took: %9.4f msec", delta * 1E3) 
end # def heartbeat 

def send_to_gearman(wrkr, workload, taskset) 
    pp workload 

    begin 
     task = Gearman::Task.new(wrkr, workload, { :priority => :high, :background => true }) 
     taskset.add_task(task) 
     taskset.wait 
    rescue => e 
     pp e 
    end # begin 
end # def send_to_gearman 

代碼的整體運行罰款分鐘,如果不在失敗前的幾個小時。具體而言,每行代碼都會重複執行,除了rescue之後的那些代碼,在出現handle_job_created錯誤之前不會失敗。

那麼,在這種情況下使用rescue Exception安全嗎?是否有一些我可以使用的異常的子集,而不是我失蹤?任何我可能忽略的更好的建議或陷阱?

回答

0

您應該只拯救實際發生的錯誤。在這種情況下,Gearman::ProtocolErrorerror being raised。所以使用:

rescue Gearman::ProtocolError 
+0

這似乎是一個更好的解決方案。我想在將其標記爲答案之前對其進行測試。你是如何確定它是Gearman :: ProtocolError的?我沒有看到我提供的錯誤行。我錯過了什麼? –

+0

@gabe,我在我的答案中鏈接到github上的行。這裏是它提出的https://github.com/gearman-ruby/gearman-ruby/blob/master/lib/gearman/taskset.rb#L99,這裏是錯誤類定義https://github.com/gearman -ruby/gearman-ruby/blob/master/lib/gearman.rb#L70-L71 – infused

+0

我的推送客戶端腳本已經運行了12個多小時。這比我運行它的時間要好。我想知道你是如何知道錯誤是什麼的,所以我可以在將來自己找到。謝謝 –