我正在尝试将后续http调用的超时设置为非常不可靠的API。我尝试过多次尝试使用Ruby的内置Timeout.timeout()方法,但是没有这么好的运气让它扩展到子调用。例如,Timeout.timeout(300)会将第一个超时设置为300,但子调用将返回60.我添加了一个seconds_delay的打印,这是我所看到的:
[16:55:16 miker@laughwhat-lm ~/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 miker@laughwhat-lm ~/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
在我执行我的requires / includes之前或之后将它添加到我的ruby文件中没有影响(即没有打印出“工作”)。希望有人有解决方案。谢谢!
答案 0 :(得分:0)
在所有各种Ruby库中,在我看来,最笨拙的工作和ugliest必须是net :: http。你有没有考虑过这样的事情:
https://github.com/dbalatero/typhoeus
typhoeus中的请求是通过lib-curl发生的,所以当嵌套或线程超时方法不受Ruby的不可靠约束时。
就rbuf_fill问题而言,我不确定是否会让你到那里。如果我没记错的话,当超时异常触发时,它总是显示代码当前位于堆栈中的位置。那个位置只是偶然的。以下面的例子我刚刚跑进了irb。注意它是如何告诉你“睡眠”中发生的超时?报告超时的时间恰好是当时正在执行的操作,而不是必须实现超时代码的地方,如果有多个超时代码,也不知道跳闸的超时。我不得不追逐rbuf_fill为你确认这一点,我现在必须跑...
IRB&GT;超时(2){sleep 5}
超时::错误:执行已过期
from(irb):3:in sleep'
from (irb):3:in
block in irb_binding'
来自(irb):3
来自/ home / ebelan