我試圖使用推客戶端的寶石從網站(近實時數據)接收推。但是,劇本往往會死去很多。搶救異常克服寶石錯誤?
如果我將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
安全嗎?是否有一些我可以使用的異常的子集,而不是我失蹤?任何我可能忽略的更好的建議或陷阱?
這似乎是一個更好的解決方案。我想在將其標記爲答案之前對其進行測試。你是如何確定它是Gearman :: ProtocolError的?我沒有看到我提供的錯誤行。我錯過了什麼? –
@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
我的推送客戶端腳本已經運行了12個多小時。這比我運行它的時間要好。我想知道你是如何知道錯誤是什麼的,所以我可以在將來自己找到。謝謝 –