2011-08-30 53 views
0

我想爲後續的http調用設置一個非常不可靠的API的超時時間。我嘗試了多次嘗試使用Ruby的內置Timeout.timeout()方法,但沒有這樣的運氣讓它擴展到子調用。例如,Timeout.timeout(300)將第一超時設置爲300,但子電話回去60.我加入了seconds_delay的打印,這裏是我所看到的:在Ruby的核心庫中修補類

[16:55:16 [email protected] ~/optisol/src/rails/tools_app/trunk/adhoc/ticket] $ bundle exec ruby buck.rb 
300 
nil 
warning: peer certificate won't be verified in this SSL session 
60 
60 
nil 
warning: peer certificate won't be verified in this SSL session 
60 

這裏是我的錯誤收到完整的堆棧跟蹤:

[16:49:50 [email protected] ~/optisol/src/rails/tools_app/trunk/adhoc/ticket] $ bundle exec ruby buck.rb 
warning: peer certificate won't be verified in this SSL session 
warning: peer certificate won't be verified in this SSL session 
warning: peer certificate won't be verified in this SSL session 
warning: peer certificate won't be verified in this SSL session 
warning: peer certificate won't be verified in this SSL session 
warning: peer certificate won't be verified in this SSL session 
warning: peer certificate won't be verified in this SSL session 
/Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/timeout.rb:64:in `rbuf_fill': execution expired (Timeout::Error) 
    from /Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/net/protocol.rb:134:in `rbuf_fill' 
    from /Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/net/protocol.rb:116:in `readuntil' 
    from /Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/net/protocol.rb:126:in `readline' 
    from /Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/net/http.rb:2028:in `read_status_line' 
    from /Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/net/http.rb:2017:in `read_new' 
    from /Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/net/http.rb:1051:in `request_without_fakeweb' 
    from /Users/miker/.rvm/gems/ree-1.8.7-2011.03/gems/fakeweb-1.3.0/lib/fake_web/ext/net_http.rb:50:in `request' 
    from /Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/net/http.rb:845:in `post' 
    from /Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/soap/netHttpClient.rb:93:in `post' 
    from /Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/soap/netHttpClient.rb:116:in `start' 
    from /Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/net/http.rb:543:in `start' 
    from /Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/soap/netHttpClient.rb:115:in `start' 
    from /Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/soap/netHttpClient.rb:92:in `post' 
    from /Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/soap/streamHandler.rb:170:in `send_post' 
    from /Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/soap/streamHandler.rb:109:in `send' 
    from /Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/soap/rpc/proxy.rb:170:in `route' 
    from /Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/soap/rpc/proxy.rb:141:in `call' 
    from /Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/soap/rpc/driver.rb:178:in `call' 
    from /Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/soap/rpc/driver.rb:232:in `getByBuyer' 
    from buck.rb:9 
    from /Users/miker/.rvm/gems/ree-1.8.7-2011.03/gems/yieldmanager-0.8.2/lib/yieldmanager/client.rb:131:in `session' 
    from buck.rb:8 
    from /Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/timeout.rb:67:in `timeout' 
    from /Users/miker/.rvm/rubies/ree-1.8.7-2011.03/lib/ruby/1.8/timeout.rb:101:in `timeout' 
    from buck.rb:6 

所以我想我的問題是我怎麼能去修補protocol.rb BufferedIO的方法是這樣的:

class BufferedIO 
    private 
    def rbuf_fill 
    puts "working" 
    timeout(300) { # forced 300 second timeout 
     @rbuf << @io.sysread(BUFSIZE) 
    } 
    end 
end 

並稱,我的ruby文件在o之前在我做我的要求/包括後沒有影響(即沒有「工作」打印出來)。希望有人有一個解決方案。謝謝!

+0

你確定它不是由於Fakeweb? Fakeweb中存在一個已知問題,它提供了相同的例外https://github.com/chrisk/fakeweb/issues/25。 WebMock(https://github.com/bblimke/webmock)在版本1.7之前有相同的問題。 –

+0

我會嘗試刪除FakeWeb的寶石,看看我能否得到它的工作。奇怪的是我可以使用超時(時間)do/end,但隻影響第一個net :: http調用。所有其他人回到60秒。非常感謝。 – Mike

回答

0

在我看來,所有各種Ruby庫中,最笨的和最醜的工作,必須是net :: http。你有沒有考慮切換到這樣的事情:嵌套或螺紋超時方法時

https://github.com/dbalatero/typhoeus

在百頭巨怪的請求通過LIB捲曲發生,因此不被約束的Ruby的不那麼可靠。

就rbuf_fill問題而言,我不確定這是否會讓您有。如果我沒有記錯,當超時異常觸發時,它總是顯示代碼當前位於堆棧中的位置。那個位置只是附帶的。以下面的例子,我只是在irb中運行。注意它是如何告訴你在「睡眠」中發生超時?在那裏報告超時正是它在那一刻所做的事情,而不是超時代碼必須執行的地方,也不知道如果有多個超時代碼是跳過的那個超時。我不得不追逐在rbuf_fill到,雖然證實了這一點給你,我不得不在此刻運行...

IRB>超時(2){睡眠5}

超時::錯誤:執行期滿從(IRB) :3:sleep' from (irb):3:in塊irb_binding從(IRB)」 :3 從/家/ ebelan

+0

你是正確的堆棧跟蹤。這就是我爲什麼選擇protocol.rb文件的原因 - 硬編碼300作爲睡眠秒數解決了我所有的問題,我想找到一種方法在運行時修補它,同時我的腳本使用它。我要看看typhoeus。 – Mike

+0

不幸的是,切換寶石將不會成爲一種選擇,因爲它需要我深入挖掘我正坐在其上的圖書館......該死的是Ruby如何讓你喜歡它。雖然謝謝! – Mike