use daemon and PIDLock
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
#!/usr/bin/env python
|
||||
# $Id: hbc,v 1.9 2012/03/29 02:08:36 andreas Exp $
|
||||
|
||||
# requre python-filelock on Linux
|
||||
# require py27-lockfile on *bsd
|
||||
# or run sudo easy_install-2.7 lockfile
|
||||
# require on Linux
|
||||
# python-filelock
|
||||
# python-daemon vs 1.61 or >
|
||||
# on *bsd
|
||||
# py27-lockfile
|
||||
# py-27-daemon
|
||||
# or run sudo easy_install-2.7 lockfile daemon
|
||||
import sys
|
||||
import time
|
||||
import socket
|
||||
@@ -14,24 +18,29 @@ import string
|
||||
import select
|
||||
import errno
|
||||
import traceback
|
||||
from lockfile import FileLock
|
||||
import lockfile
|
||||
import daemon
|
||||
import daemon.pidfile
|
||||
import syslog
|
||||
|
||||
|
||||
PORT=50003
|
||||
INTERVAL=10
|
||||
DBG = True
|
||||
|
||||
sock=None
|
||||
sock = None
|
||||
up = True
|
||||
ackcount = 0
|
||||
|
||||
class NullDevice:
|
||||
def write(self, s):
|
||||
pass
|
||||
|
||||
|
||||
def handler(signum, frame):
|
||||
global up
|
||||
if up == 0:
|
||||
return
|
||||
sys.exit(0)
|
||||
def syslogtrace(note):
|
||||
logm = '%s hbc died: \n%s' % (note, traceback.format_exc())
|
||||
for l in logm.split('\n'):
|
||||
syslog.syslog(' tb: %s' % l)
|
||||
|
||||
|
||||
def getsock(host):
|
||||
@@ -46,35 +55,43 @@ def getsock(host):
|
||||
else:
|
||||
return None
|
||||
if verbose:
|
||||
print "socktype: %s" % af_type
|
||||
syslog.syslog("socktype: %s" % af_type)
|
||||
sock=socket.socket(af_type, socket.SOCK_DGRAM)
|
||||
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, \
|
||||
sock.getsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR) | 1)
|
||||
if verbose: print "get socket %s" % sock
|
||||
if verbose: syslog.syslog("get socket %s" % sock)
|
||||
|
||||
return sock
|
||||
|
||||
|
||||
def socksend(msg, tohost):
|
||||
global sock
|
||||
|
||||
if sock == None:
|
||||
sock=getsock(tohost[0])
|
||||
sock.sendto(msg, tohost)
|
||||
if verbose: print "msg %s sent" % msg
|
||||
if verbose: syslog.syslog("msg %s sent" % msg)
|
||||
|
||||
|
||||
def process():
|
||||
global up, sock, ackcount
|
||||
|
||||
if sock == None:
|
||||
sock=getsock(tohost[0])
|
||||
|
||||
ackcount=0
|
||||
lastT=time.time()
|
||||
while up:
|
||||
sleep=(lastT+interval) - time.time()
|
||||
if verbose: print "sleep %s" % sleep
|
||||
if verbose: syslog.syslog("sleep %s" % sleep)
|
||||
if sleep > 0:
|
||||
try:
|
||||
r=select.select([sock.fileno()],[],[],sleep)
|
||||
# time.sleep(interval)
|
||||
except:
|
||||
if up:
|
||||
syslogtrace('select')
|
||||
break
|
||||
if verbose: print r
|
||||
if verbose: syslog.syslog("r is %s" % str(r))
|
||||
if sock.fileno() in r[0]:
|
||||
data, addr = sock.recvfrom(1024)
|
||||
if data == "ACK":
|
||||
@@ -83,22 +100,35 @@ def process():
|
||||
try:
|
||||
os.system(data)
|
||||
except:
|
||||
syslogtrace('System')
|
||||
pass
|
||||
continue
|
||||
lastT=time.time()
|
||||
for hb_host in hb_hosts:
|
||||
try:
|
||||
msg="interval=%s;name=%s;time=%s;acks=%s" % (interval, iam, time.time(), ackcount)
|
||||
if verbose: print "sock.send('%s', (%s, %s))" % (msg, hb_host, hb_port)
|
||||
if verbose: syslog.syslog("sock.send('%s', (%s, %s))" % (msg, hb_host, hb_port))
|
||||
socksend(msg, (hb_host, hb_port))
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def cleanup(a, b):
|
||||
global up, sock, ackcount
|
||||
up = False
|
||||
syslog.syslog('exit a=%s b=%s' % (str(a), str(b)))
|
||||
msg="shutdown=1;name=%s;acks=%s" % (iam, ackcount)
|
||||
for hb_host in hb_hosts:
|
||||
if verbose: syslog.syslog("hbc: sock.send('%s', (%s, %s))" % (msg, hb_host, hb_port))
|
||||
socksend(msg, (hb_host, hb_port))
|
||||
time.sleep(1)
|
||||
sock.close()
|
||||
|
||||
|
||||
msgonly=False
|
||||
helpflag=False
|
||||
verbose=False
|
||||
daemon=False
|
||||
fdaemon=False
|
||||
optlist=[]
|
||||
args=[]
|
||||
msgboot=[]
|
||||
@@ -116,7 +146,7 @@ for o,a in optlist:
|
||||
elif o == '-c':
|
||||
configfile=a
|
||||
elif o == '-d':
|
||||
daemon=True
|
||||
fdaemon=True
|
||||
elif o == '-h':
|
||||
helpflag=True
|
||||
elif o == '-m':
|
||||
@@ -228,47 +258,29 @@ if msgonly:
|
||||
|
||||
#
|
||||
#
|
||||
if daemon:
|
||||
pid=os.fork()
|
||||
if pid > 0:
|
||||
if verbose:
|
||||
print "daemoinizing... pid=%d" % pid
|
||||
sys.exit(0)
|
||||
syslog.openlog(logoption=syslog.LOG_PID, facility=syslog.LOG_DAEMON)
|
||||
if fdaemon:
|
||||
print "daemoinizing... %s" % os.getpid()
|
||||
|
||||
context = daemon.DaemonContext(
|
||||
working_directory='/tmp',
|
||||
umask=0o002,
|
||||
pidfile=daemon.pidfile.TimeoutPIDLockFile('/tmp/hbc.pid', acquire_timeout=-1),
|
||||
)
|
||||
|
||||
if not DBG:
|
||||
os.close(0)
|
||||
os.close(1)
|
||||
os.close(2)
|
||||
sys.stdin.close()
|
||||
sys.stdout = NullDevice()
|
||||
sys.stderr = NullDevice()
|
||||
os.chdir("/")
|
||||
os.setsid()
|
||||
os.umask(0)
|
||||
context.signal_map = {
|
||||
signal.SIGTERM: cleanup,
|
||||
signal.SIGHUP: 'terminate',
|
||||
# signal.SIGUSR1: reload_program_config,
|
||||
}
|
||||
|
||||
context.files_preserve = [sock, sock.fileno()]
|
||||
with context:
|
||||
syslog.syslog('starting heartbeat to %s' % ','.join(hb_hosts))
|
||||
up = True
|
||||
try:
|
||||
process()
|
||||
except:
|
||||
syslogtrace('process')
|
||||
cleanup(0, None)
|
||||
|
||||
lock = FileLock('/tmp/hbc.pid')
|
||||
lock.acquire()
|
||||
|
||||
up=1
|
||||
signal.signal(signal.SIGTERM, handler)
|
||||
signal.signal(signal.SIGHUP, handler)
|
||||
|
||||
|
||||
|
||||
try:
|
||||
process()
|
||||
except:
|
||||
data='hbc died:\n'+traceback.format_exc()
|
||||
open("/tmp/hbc.log","a").write(data)
|
||||
sys.exit(1)
|
||||
|
||||
up=0
|
||||
msg="shutdown=1;name=%s;acks=%s" % (iam, ackcount)
|
||||
for hb_host in hb_hosts:
|
||||
if verbose: print "hbc: sock.send('%s', (%s, %s))" % (msg, hb_host, hb_port)
|
||||
socksend(msg, (hb_host, hb_port))
|
||||
time.sleep(1)
|
||||
sock.close()
|
||||
lock.release()
|
||||
|
||||
Reference in New Issue
Block a user