2011-08-30 56 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