move to python 3, fix rtt

This commit is contained in:
2019-12-16 12:03:43 -05:00
parent 778c874cee
commit 8d9af90168
+87 -60
View File
@@ -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()