move to python 3, fix rtt
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/env python2
|
#!/usr/bin/env python
|
||||||
# $Id: hbc,v 1.9 2012/03/29 02:08:36 andreas Exp $
|
# $Id: hbc,v 1.9 2012/03/29 02:08:36 andreas Exp $
|
||||||
# NEW
|
# NEW
|
||||||
import sys
|
import sys
|
||||||
@@ -11,7 +11,7 @@ import string
|
|||||||
import select
|
import select
|
||||||
import errno
|
import errno
|
||||||
import traceback
|
import traceback
|
||||||
import md5
|
from hashlib import md5
|
||||||
import shutil
|
import shutil
|
||||||
import zlib
|
import zlib
|
||||||
import subprocess
|
import subprocess
|
||||||
@@ -35,7 +35,7 @@ def log(msg):
|
|||||||
if fdaemon:
|
if fdaemon:
|
||||||
syslog.syslog(syslog.LOG_ERR, msg)
|
syslog.syslog(syslog.LOG_ERR, msg)
|
||||||
else:
|
else:
|
||||||
print msg
|
print(msg)
|
||||||
|
|
||||||
def handler(signum, frame):
|
def handler(signum, frame):
|
||||||
if signum == signal.SIGTERM:
|
if signum == signal.SIGTERM:
|
||||||
@@ -82,7 +82,7 @@ class Conn:
|
|||||||
msg['id'] = self.conId
|
msg['id'] = self.conId
|
||||||
msg['ver'] = VER
|
msg['ver'] = VER
|
||||||
msg['time'] = time.time()
|
msg['time'] = time.time()
|
||||||
m = dicttos(ID, msg, True) # always compress
|
m = dicttos(ID, msg) # always compress
|
||||||
if verbose:
|
if verbose:
|
||||||
log("conn.send('%s', (%s:%s) %s)" % (msg, self.addr, self.port, len(m)))
|
log("conn.send('%s', (%s:%s) %s)" % (msg, self.addr, self.port, len(m)))
|
||||||
try:
|
try:
|
||||||
@@ -93,14 +93,20 @@ class Conn:
|
|||||||
self.close()
|
self.close()
|
||||||
return
|
return
|
||||||
self.send += 1
|
self.send += 1
|
||||||
self.lastsend = time.time()
|
self.lastsend = msg['time']
|
||||||
|
print("RTT self.lastsend %s" % self.lastsend)
|
||||||
|
|
||||||
|
|
||||||
def ack(self, msgDict):
|
def ack(self, msgDict, now):
|
||||||
self.lastack = time.time()
|
try:
|
||||||
self.lastacksent = float(msgDict.get('time','0'))
|
self.lastack = msgDict['time']
|
||||||
if verbose: log("ack RTT: %0.1f ms" % ((self.lastack - self.lastsend) * 1000.0))
|
mul = 2
|
||||||
self.rtts.append((self.lastack - self.lastsend) * 1000.0)
|
except:
|
||||||
|
self.lastack = now
|
||||||
|
mul = 1
|
||||||
|
rtt = (self.lastack - self.lastsend) * mul
|
||||||
|
if verbose: log("ack RTT: %0.1f ms (now %s)" % (rtt * 1000.0, now))
|
||||||
|
self.rtts.append(rtt * 1000.0)
|
||||||
if len(self.rtts) > 10:
|
if len(self.rtts) > 10:
|
||||||
del self.rtts[0]
|
del self.rtts[0]
|
||||||
self.ackcount += 1
|
self.ackcount += 1
|
||||||
@@ -113,11 +119,11 @@ class Conn:
|
|||||||
|
|
||||||
|
|
||||||
def shortname(name):
|
def shortname(name):
|
||||||
r = string.split(name, '.')
|
r = name.split('.')
|
||||||
return r[0]
|
return r[0]
|
||||||
|
|
||||||
|
|
||||||
def dicttos(ID, d, compress=False):
|
def dicttos(ID, d):
|
||||||
s = []
|
s = []
|
||||||
for k in d:
|
for k in d:
|
||||||
if type(d[k]) == type(1.2):
|
if type(d[k]) == type(1.2):
|
||||||
@@ -125,15 +131,35 @@ def dicttos(ID, d, compress=False):
|
|||||||
else:
|
else:
|
||||||
s.append("%s=%s" % (k, d[k]))
|
s.append("%s=%s" % (k, d[k]))
|
||||||
pk = ";".join(s)
|
pk = ";".join(s)
|
||||||
if compress:
|
zpk = zlib.compress(pk.encode(), 6)
|
||||||
zpk = zlib.compress(pk, 6)
|
ID = "!" + ID + ":"
|
||||||
ID = "!"+ID
|
return ID.encode() + zpk
|
||||||
else:
|
|
||||||
zpk = pk
|
|
||||||
return ID + ":" + zpk
|
|
||||||
|
|
||||||
|
|
||||||
def stodict(msg):
|
def stodict(msg):
|
||||||
|
d = {}
|
||||||
|
if len(msg) > 0 and chr(msg[0]) == "!":
|
||||||
|
pk = zlib.decompress(msg[5:]).decode()
|
||||||
|
d['ID'] = msg[1:4].decode()
|
||||||
|
else:
|
||||||
|
r0 = msg.split(':',1)
|
||||||
|
pk = r0[1]
|
||||||
|
d['ID'] = r0[0]
|
||||||
|
r = pk.split(';')
|
||||||
|
for v in r:
|
||||||
|
vr = v.split('=', 1)
|
||||||
|
k = vr[0].strip()
|
||||||
|
if len(vr) == 1:
|
||||||
|
d[k] = None
|
||||||
|
else:
|
||||||
|
v = vr[1].strip()
|
||||||
|
if v[0].isdigit():
|
||||||
|
v = eval(v)
|
||||||
|
d[k] = v
|
||||||
|
print("DBG: msg is %s" % d)
|
||||||
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
def XXstodict(msg):
|
||||||
d = {}
|
d = {}
|
||||||
r0 = msg.split(':',1)
|
r0 = msg.split(':',1)
|
||||||
if len(r0) == 1:
|
if len(r0) == 1:
|
||||||
@@ -167,7 +193,7 @@ def syslogtrace(note):
|
|||||||
for l in logm.split('\n'):
|
for l in logm.split('\n'):
|
||||||
syslog.syslog(syslog.LOG_ERR, ' tb: %s' % l)
|
syslog.syslog(syslog.LOG_ERR, ' tb: %s' % l)
|
||||||
if verbose:
|
if verbose:
|
||||||
print logm
|
print(logm)
|
||||||
|
|
||||||
|
|
||||||
conId = 1
|
conId = 1
|
||||||
@@ -188,13 +214,13 @@ def createConnections(hosts):
|
|||||||
elif r[0] == 2:
|
elif r[0] == 2:
|
||||||
af=socket.AF_INET
|
af=socket.AF_INET
|
||||||
else:
|
else:
|
||||||
print "dont know this net type: %s" % r[0][0]
|
print("dont know this net type: %s" % r[0][0])
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
addr = r[4][0]
|
addr = r[4][0]
|
||||||
conns[conId] = Conn(conId, addr, hb_port, af)
|
conns[conId] = Conn(conId, addr, hb_port, af)
|
||||||
if verbose:
|
if verbose:
|
||||||
print "cons[%s] = %s" % (conId, str(conns[conId]))
|
print("cons[%s] = %s" % (conId, str(conns[conId])))
|
||||||
conId += 1
|
conId += 1
|
||||||
|
|
||||||
|
|
||||||
@@ -258,14 +284,14 @@ def doupdateone(code, csum):
|
|||||||
|
|
||||||
def restart():
|
def restart():
|
||||||
if verbose:
|
if verbose:
|
||||||
print "restart: execv %s %s" % (sys.argv[0], [sys.argv[0]]+cmdargs)
|
print("restart: execv %s %s" % (sys.argv[0], [sys.argv[0]]+cmdargs))
|
||||||
syslog.syslog(syslog.LOG_ERR, 'restart %s' % (sys.argv[0]))
|
syslog.syslog(syslog.LOG_ERR, 'restart %s' % (sys.argv[0]))
|
||||||
e = "fallthrough"
|
e = "fallthrough"
|
||||||
try:
|
try:
|
||||||
os.execv(sys.argv[0], [sys.argv[0]]+cmdargs)
|
os.execv(sys.argv[0], [sys.argv[0]]+cmdargs)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
pass
|
pass
|
||||||
print "should not be here:", str(e)
|
print("should not be here:", str(e))
|
||||||
log('restart failed: %s' % e)
|
log('restart failed: %s' % e)
|
||||||
|
|
||||||
|
|
||||||
@@ -287,7 +313,8 @@ def process():
|
|||||||
if sleep <= 0:
|
if sleep <= 0:
|
||||||
break
|
break
|
||||||
try:
|
try:
|
||||||
r=select.select(ifiles.keys(),[],[],sleep)
|
r=select.select(list(ifiles.keys()),[],[],sleep)
|
||||||
|
now = time.time() # nb: delay from actual packet arrival to select is ca. 105ms!
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
running = False
|
running = False
|
||||||
break
|
break
|
||||||
@@ -304,16 +331,16 @@ def process():
|
|||||||
for rfh in r[0]:
|
for rfh in r[0]:
|
||||||
conn = conIds[rfh]
|
conn = conIds[rfh]
|
||||||
data, addr = ifiles[rfh].recvfrom(MAXRECV)
|
data, addr = ifiles[rfh].recvfrom(MAXRECV)
|
||||||
if verbose: print "sock.recvfrom: %s (%s) %s" % (addr, len(data), data[:4])
|
# if verbose: print("sock.recvfrom: %s (%s) %s" % (addr, len(data), data[:4]))
|
||||||
msgDict = stodict(data)
|
msgDict = stodict(data)
|
||||||
if verbose: print "sock.recvfrom: %s (%s) %s" % (addr, len(data), str(msgDict)[:80])
|
if verbose: print("sock.recvfrom: %s (%s) %s" % (addr, len(data), str(msgDict)[:80]))
|
||||||
if msgDict == None:
|
if msgDict == None:
|
||||||
print "bad backet from %s (%s) %s" % (addr, len(data), data)
|
print("bad backet from %s (%s) %s" % (addr, len(data), data))
|
||||||
elif msgDict['ID'] == "ACK":
|
elif msgDict['ID'] == "ACK":
|
||||||
conns[conn].ack(msgDict)
|
conns[conn].ack(msgDict, now)
|
||||||
elif msgDict['ID'] == "UPD":
|
elif msgDict['ID'] == "UPD":
|
||||||
if doupdate(conn, msgDict) == None:
|
if doupdate(conn, msgDict) == None:
|
||||||
if verbose: print "process: restart after update"
|
if verbose: print("process: restart after update")
|
||||||
dorestart = True
|
dorestart = True
|
||||||
break
|
break
|
||||||
elif msgDict['ID'] == "CMD":
|
elif msgDict['ID'] == "CMD":
|
||||||
@@ -369,7 +396,7 @@ def daemonize(working_dir="/", stdin='/dev/zero', stdout='/dev/null', stderr='/d
|
|||||||
if pid > 0:
|
if pid > 0:
|
||||||
# exit from first parent
|
# exit from first parent
|
||||||
os._exit(0)
|
os._exit(0)
|
||||||
except OSError, e:
|
except OSError as e:
|
||||||
sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
|
sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
|
||||||
os._exit(1)
|
os._exit(1)
|
||||||
|
|
||||||
@@ -383,7 +410,7 @@ def daemonize(working_dir="/", stdin='/dev/zero', stdout='/dev/null', stderr='/d
|
|||||||
if pid > 0:
|
if pid > 0:
|
||||||
# exit from second parent
|
# exit from second parent
|
||||||
os._exit(0)
|
os._exit(0)
|
||||||
except OSError, e:
|
except OSError as e:
|
||||||
sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
|
sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
@@ -438,20 +465,20 @@ for o,a in optlist:
|
|||||||
|
|
||||||
|
|
||||||
cmdargs += args
|
cmdargs += args
|
||||||
if verbose: print "cmdargs for restart are %s" % cmdargs
|
if verbose: print("cmdargs for restart are %s" % cmdargs)
|
||||||
|
|
||||||
if helpflag:
|
if helpflag:
|
||||||
print "hbc HeartBeatClient"
|
print("hbc HeartBeatClient")
|
||||||
print "usage: hbc [-bdhv] [-c configfile] [-m msg][host1 [..]]"
|
print("usage: hbc [-bdhv] [-c configfile] [-m msg][host1 [..]]")
|
||||||
print
|
print()
|
||||||
print " -b indicate machine boot"
|
print(" -b indicate machine boot")
|
||||||
print " -c configfile"
|
print(" -c configfile")
|
||||||
print " -d daemonize"
|
print(" -d daemonize")
|
||||||
print " -h this help"
|
print(" -h this help")
|
||||||
print " -m send a message"
|
print(" -m send a message")
|
||||||
print " -v verbose"
|
print(" -v verbose")
|
||||||
print
|
print()
|
||||||
print """ config file can contain
|
print(""" config file can contain
|
||||||
hb_hosts=('host1', 'host2', ..._
|
hb_hosts=('host1', 'host2', ..._
|
||||||
hb_port=50003
|
hb_port=50003
|
||||||
interval=20
|
interval=20
|
||||||
@@ -459,7 +486,7 @@ logfile=...
|
|||||||
logfmt={|test|msg}
|
logfmt={|test|msg}
|
||||||
grace=SECONDS
|
grace=SECONDS
|
||||||
reportstrict={True|False}
|
reportstrict={True|False}
|
||||||
"""
|
""")
|
||||||
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
@@ -473,9 +500,9 @@ iam=socket.gethostname()
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
f=open(configfile,"r")
|
f=open(configfile,"r")
|
||||||
if verbose: print "notice: using config file %s" % configfile
|
if verbose: print("notice: using config file %s" % configfile)
|
||||||
except:
|
except:
|
||||||
if verbose: print "warning: running without config file: %s" % configfile
|
if verbose: print("warning: running without config file: %s" % configfile)
|
||||||
f=None
|
f=None
|
||||||
|
|
||||||
if f:
|
if f:
|
||||||
@@ -487,14 +514,14 @@ if f:
|
|||||||
if r[0] == 'hb_hosts':
|
if r[0] == 'hb_hosts':
|
||||||
hb_hosts=eval(r[1])
|
hb_hosts=eval(r[1])
|
||||||
if verbose:
|
if verbose:
|
||||||
print "notice: cfg hb_hosts: %s" % hb_hosts
|
print("notice: cfg hb_hosts: %s" % hb_hosts)
|
||||||
elif r[0] == 'interval':
|
elif r[0] == 'interval':
|
||||||
interval=eval(r[1])
|
interval=eval(r[1])
|
||||||
elif r[0] == 'hb_port':
|
elif r[0] == 'hb_port':
|
||||||
hb_port=eval(r[1])
|
hb_port=eval(r[1])
|
||||||
elif r[0] == 'name':
|
elif r[0] == 'name':
|
||||||
iam=eval(r[1])
|
iam=eval(r[1])
|
||||||
if verbose: print "name set to %s" % iam
|
if verbose: print("name set to %s" % iam)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
if len(args) != 0:
|
if len(args) != 0:
|
||||||
@@ -502,17 +529,17 @@ if len(args) != 0:
|
|||||||
|
|
||||||
|
|
||||||
if len(hb_hosts) == 0:
|
if len(hb_hosts) == 0:
|
||||||
print "no hb server specified"
|
print("no hb server specified")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
#
|
#
|
||||||
if verbose:
|
if verbose:
|
||||||
print "notice: hb_hosts: %s" % str(hb_hosts)
|
print("notice: hb_hosts: %s" % str(hb_hosts))
|
||||||
print "notice: hb_port: %s" % hb_port
|
print("notice: hb_port: %s" % hb_port)
|
||||||
print "notice: interval: %s" % interval
|
print("notice: interval: %s" % interval)
|
||||||
print "notice: iam: %s" % iam
|
print("notice: iam: %s" % iam)
|
||||||
print "notice: msgonly: %s" % msgonly
|
print("notice: msgonly: %s" % msgonly)
|
||||||
print "notice: msgboot: %s" % msgboot
|
print("notice: msgboot: %s" % msgboot)
|
||||||
|
|
||||||
if not msgonly:
|
if not msgonly:
|
||||||
msgboot['interval'] = interval
|
msgboot['interval'] = interval
|
||||||
@@ -531,20 +558,20 @@ if verbose:
|
|||||||
log("%s connections created" % (len(conns)))
|
log("%s connections created" % (len(conns)))
|
||||||
|
|
||||||
if len(msgboot) > 0:
|
if len(msgboot) > 0:
|
||||||
if verbose: print "on boot"
|
if verbose: print("on boot")
|
||||||
msgboot['acks'] = 0
|
msgboot['acks'] = 0
|
||||||
for conn in conns:
|
for conn in conns:
|
||||||
conns[conn].sendto(msgboot)
|
conns[conn].sendto(msgboot)
|
||||||
|
|
||||||
if msgonly:
|
if msgonly:
|
||||||
if verbose: print "msgboot done msgonly=%s" % msgonly
|
if verbose: print("msgboot done msgonly=%s" % msgonly)
|
||||||
closeall()
|
closeall()
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
#
|
#
|
||||||
syslog.openlog('hbc', syslog.LOG_PID, syslog.LOG_DAEMON)
|
syslog.openlog('hbc', syslog.LOG_PID, syslog.LOG_DAEMON)
|
||||||
if fdaemon:
|
if fdaemon:
|
||||||
print "daemoinizing."
|
print("daemoinizing.")
|
||||||
daemonize()
|
daemonize()
|
||||||
daemonized = True
|
daemonized = True
|
||||||
syslog.syslog(syslog.LOG_ERR, 'starting heartbeat to %s' % ','.join(hb_hosts))
|
syslog.syslog(syslog.LOG_ERR, 'starting heartbeat to %s' % ','.join(hb_hosts))
|
||||||
@@ -555,7 +582,7 @@ try:
|
|||||||
process()
|
process()
|
||||||
except:
|
except:
|
||||||
syslogtrace('process')
|
syslogtrace('process')
|
||||||
if verbose: print "err: process exit: %s" % e
|
if verbose: print("err: process exit: %s" % e)
|
||||||
|
|
||||||
if verbose: log( "main: cleanup")
|
if verbose: log( "main: cleanup")
|
||||||
cleanup()
|
cleanup()
|
||||||
|
|||||||
Reference in New Issue
Block a user