X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=lib%2Frbot%2Fircbot.rb;h=92f5fe55c88c400601abeb76367f2c8c189cec95;hb=498a240496b65b897572e3fde3ef19b296e9c003;hp=bd75bec5d5039f4822d01a8a5460eaba3f4eea52;hpb=2a3bc07d139593f1f57e23cfbd08602d29a8b26c;p=user%2Fhenk%2Fcode%2Fruby%2Frbot.git diff --git a/lib/rbot/ircbot.rb b/lib/rbot/ircbot.rb index bd75bec5..92f5fe55 100644 --- a/lib/rbot/ircbot.rb +++ b/lib/rbot/ircbot.rb @@ -959,7 +959,7 @@ class Bot end # disconnect the bot from IRC, if connected, and then connect (again) - def reconnect(message=nil, too_fast=false) + def reconnect(message=nil, too_fast=0) # we will wait only if @last_rec was not nil, i.e. if we were connected or # got disconnected by a network error # if someone wants to manually call disconnect() _and_ reconnect(), they @@ -978,11 +978,22 @@ class Bot log "\n\nWaiting to reconnect\n\n" sleep @config['server.reconnect_wait'] - sleep 10*@config['server.reconnect_wait'] if too_fast + if too_fast > 0 + tf = too_fast*@config['server.reconnect_wait'] + tfu = Utils.secs_to_string(tf) + log "Will sleep for an extra #{tf}s (#{tfu})" + sleep tf + end end connect + rescue DBFatal => e + fatal "fatal db error: #{e.pretty_inspect}" + DBTree.stats + log_session_end + exit 2 rescue Exception => e + error e will_wait = true retry end @@ -991,11 +1002,13 @@ class Bot # begin event handling loop def mainloop while true - too_fast = false + too_fast = 0 quit_msg = nil + valid_recv = false # did we receive anything (valid) from the server yet? begin reconnect(quit_msg, too_fast) quit if $interrupted > 0 + valid_recv = false while @socket.connected? quit if $interrupted > 0 @@ -1007,6 +1020,8 @@ class Bot break unless reply = @socket.gets @last_rec = Time.now @client.process reply + valid_recv = true + too_fast = 0 else ping_server end @@ -1021,10 +1036,39 @@ class Bot rescue Errno::ETIMEDOUT, Errno::ECONNABORTED, TimeoutError, SocketError => e error "network exception: #{e.pretty_inspect}" quit_msg = e.to_s + too_fast += 10 if valid_recv + rescue ServerMessageParseError => e + # if the bot tried reconnecting too often, we can get forcefully + # disconnected by the server, while still receiving an empty message + # wait at least 10 minutes in this case + if e.message.empty? + oldtf = too_fast + too_fast = [too_fast, 300].max + too_fast*= 2 + log "Empty message from server, extra delay multiplier #{oldtf} -> #{too_fast}" + end + quit_msg = "Unparseable Server Message: #{e.message.inspect}" + retry rescue ServerError => e - # received an ERROR from the server quit_msg = "server ERROR: " + e.message - too_fast = e.message.index("reconnect too fast") + debug quit_msg + idx = e.message.index("connect too fast") + debug "'connect too fast' @ #{idx}" + if idx + oldtf = too_fast + too_fast += (idx+1)*2 + log "Reconnecting too fast, extra delay multiplier #{oldtf} -> #{too_fast}" + end + idx = e.message.index(/a(uto)kill/i) + debug "'autokill' @ #{idx}" + if idx + # we got auto-killed. since we don't have an easy way to tell + # if it's permanent or temporary, we just set a rather high + # reconnection timeout + oldtf = too_fast + too_fast += (idx+1)*5 + log "Killed by server, extra delay multiplier #{oldtf} -> #{too_fast}" + end retry rescue DBFatal => e fatal "fatal db error: #{e.pretty_inspect}"