Author: bdonlan
Date: 2005-07-24 00:18:06 -0400 (Sun, 24 Jul 2005)
New Revision: 888
Modified:
trunk/clients/ravish/ravish2.rb
Log:
Lag checks; passive and active
Modified: trunk/clients/ravish/ravish2.rb
===================================================================
--- trunk/clients/ravish/ravish2.rb 2005-07-20 02:11:28 UTC (rev 887)
+++ trunk/clients/ravish/ravish2.rb 2005-07-24 04:18:06 UTC (rev 888)
@@ -57,14 +57,17 @@
'port' => 7575,
'nick' => ENV['USER'] || 'RavishUser',
'password' => '',
+ 'lag_interval' => 30,
}
ConfFile = '.ravishrc'
+
def initialize conffile = ConfFile
@conffile = conffile
loadconf
at_exit { saveconf }
+ lag_init # must init early or we'll crash
@term = Term::Visual.new
@term.palette.setcolors Palette
@term.global_prefix = self.method :global_prefix
@@ -100,6 +103,7 @@
@term.resize
end
}
+
end
def do_resize
@@ -143,6 +147,7 @@
when :message_sent
srvmsg "%(cmesg)C: #{args[0].inspect}"
when :message_received
+ lag_check_msg args[0]
srvmsg "%(smesg)S: #{args[0].inspect}"
else
if type.to_s =~ /^ev_([A-Z:]+)$/
@@ -271,9 +276,117 @@
}.join("%(statdecs),%(status)") +
"%(statdecs)]%(status)"
end
+ if @lag.nil?
+ status += " nil-lag"
+
+ else # if @lag > 0 # XXX
+ status += sprintf \
+ " %%(statdecs)[%%(status)Lag: %0.3f%%(statdecs)]%%(status)",
+ @lag
+ end
win.window.status = status
end
+ ## LAG MEASUREMENT
+
+ # Some quick notes on lagchecking:
+ # @lag_st = :synced | :syncing | :off
+ # :synced means the events listed in @lag_ev are expected to come in order
+ # :syncing means that a C: POKE has been issued and no other items should
+ # be in @lag_st. Once the S: OUCH is received, go back to :synced
+ # :off means lag checking is off. Currently no UI.
+
+ # @lag_ev = [ [ #time, "IN", ... ], ... ]
+ # A list of server events we expect to receive, in the order we expect to
+ # receive them. S: FAIL will be accepted as well. The server must not
+ # issue events exactly as described here. No untracked events of a tracked
+ # type may be issued - eg, C: IN without adding to @lag_ev via
+ # lag_expect_ev is forbidden.
+
+ # @lag = 0.1212445
+ # RTT in floating-point seconds
+
+ # @lag_last = #time
+ # Time of last lag measurement
+
+ # Functions:
+ # lag_expect [ "IN", ... ]
+ # expect the given event from the server, or a FAIL of the same event
+ # name.
+ # lag_resync
+ # Discard @lag_ev, issue a C: POKE, set @lag_st to :syncing.
+
+ # Currently tracked:
+ # IN, JOIN, PART
+
+ def lag_init
+ @lag_st = :synced
+ @lag_ev = []
+ @lag = 0
+ end
+
+ def lag_expect *evt
+ if @lag_st == :off then return end
+ now = Time.now
+ @lag_ev.push [now, evt]
+ end
+
+ def lag_resync
+ if @lag_st == :off then return end
+ now = Time.now
+ str = now.to_s
+ @lag_st = :syncing
+ @lag_ev = [ [ now, [ "OUCH", str ] ] ]
+ @haver.msg 'POKE', str
+ end
+
+ def lag_debug
+ srvmsg "lag_st [EMAIL PROTECTED]"
+ srvmsg "lag_ev [EMAIL PROTECTED]"
+ end
+
+ def lag_check_msg evt
+ lag_debug
+ srvmsg "evt [EMAIL PROTECTED]"
+ if @lag_st == :off then return end
+ if @lag_ev.empty? then return end
+ if evt[0] == 'FAIL'
+ if evt[1] != @lag_ev[0][1][0] # First event, message section, cmd
+ return
+ end
+ else
+ if evt != @lag_ev[0][1]
+ return
+ end
+ end
+ ev_s = @lag_ev.shift
+ time = ev_s[0]
+ @lag = Time.now - time
+ @lag_last = Time.now
+ statbar_update
+ lag_sched_ping
+ end
+
+ def lag_sched_ping
+ if @conf['lag_interval'].nil? || @conf['lag_interval'] <= 0
+ return
+ end
+ EventManager.instance.in @conf['lag_interval'], method(:lag_ping)
+ end
+
+ def lag_ping junk=nil
+ if @lag_last.nil? then return end
+ if Time.now - @lag_last < @conf['lag_interval'] then return end
+ lag_ping_force
+ end
+
+ def lag_ping_force
+ now_s = Time.now.to_s
+ @haver.msg 'POKE', now_s
+ lag_expect 'OUCH', now_s
+ @lag_last = nil
+ end
+
## SERVER MESSAGES ##
def unknown_ev cmd, args
@@ -311,6 +424,7 @@
srvmsg "Server accepted uid #{nick}"
@nick = nick
activity @servwin, 2
+ lag_ping_force
end
def ev_PING data
@@ -443,6 +557,7 @@
case win.type
when :channel
@haver.msg 'IN', win['channel'], 'say', line
+ lag_expect 'IN', win['channel'], @nick, 'say', line
when :query
win.window.addline line, "%(nickdecs)<%(mynick)[EMAIL
PROTECTED]" +
"%(nickdecs)>%(default) "
@@ -453,6 +568,7 @@
def user_RAW args
if args.length >= 1
@haver.msg args.shift.upcase, *args
+ lag_resync # Who knows what dastardly deeds are afoot?
end
end
@@ -466,6 +582,7 @@
case win.type
when :channel
@haver.msg 'IN', win['channel'], 'say', line.join(' ')
+ lag_expect 'IN', win['channel'], @nick, 'say', line.join(' ')
when :query
win.window.addline line.join(' '),
"%(nickdecs)<%(mynick)[EMAIL PROTECTED]" +
"%(nickdecs)>%(default) "
@@ -478,6 +595,7 @@
case win.type
when :channel
@haver.msg 'IN', win['channel'], 'do', line.join(' ')
+ lag_expect 'IN', win['channel'], @nick, 'do', line.join(' ')
when :query
win.window.addline line.join(' '), "%(donick)* [EMAIL
PROTECTED](default) "
@haver.msg 'TO', win['uid'], 'do', line.join(' ')
@@ -520,14 +638,21 @@
return
end
@haver.msg 'JOIN', args[0]
+ lag_expect 'JOIN', args[0], @nick
end
def user_PART args
+ channel = nil # establish scope
if args[0]
@haver.msg 'PART', args[0]
+ channel = args[0]
elsif win = find_window(@term.current_window) and win.type ==
:channel
@haver.msg 'PART', win['channel']
+ channel = win['channel']
end
+ if !channel.nil?
+ lag_expect 'PART', channel, @nick
+ end
end
def user_NAMES args