-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdaemon.py
executable file
·117 lines (90 loc) · 2.81 KB
/
daemon.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#
# Thanks to: https://web.archive.org/web/20131017130434/http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
#
import atexit
import logging
import os
import sys
import time
from signal import SIGTERM
from bot import Bot
class Daemon:
pid = None
pidfile = "./configs/rb.pid"
logfile = "./configs/rb.log"
def __init__(self):
# setup logger
self.logger = logging.getLogger("Recordurbate")
self.logger.setLevel(logging.DEBUG)
fh = logging.FileHandler(self.logfile)
fh.setLevel(logging.DEBUG)
fh.setFormatter(logging.Formatter("%(asctime)s - %(message)s"))
self.logger.addHandler(fh)
def daemonize(self):
self.logger.info("Starting daemon")
# double fork
try:
pid = os.fork()
if pid > 0:
sys.exit(0)
pid = os.fork()
if pid > 0:
sys.exit(0)
except OSError as e:
self.logger.info("Failed to daemonize, {}".format(e))
print("Failed to daemonize, {}".format(e))
sys.exit(1)
# close std's
sys.stdin.close()
sys.stdout.close()
sys.stderr.close()
# write pid file
self.pid = os.getpid()
with open(self.pidfile, "w+") as pf:
pf.write("{}\n".format(self.pid))
# register remove
atexit.register(os.remove, self.pidfile)
self.logger.info("Successfully started daemon, pid: {}".format(self.pid))
def read_pid(self):
try:
with open(self.pidfile) as pf:
return int(pf.read().strip())
except IOError:
return None
def start(self):
# check pid file
pid = self.read_pid()
# if found, exit
if pid:
print("Pid file found, is Recordurbate already running? pid: {}".format(pid))
sys.exit(1)
# continue
self.daemonize()
self.run(self.logger)
def stop(self):
# check pid file
pid = self.read_pid()
if not pid:
print("Pid file not found, Daemon not running?")
return
# try and kill
try:
while True:
os.kill(pid, SIGTERM)
time.sleep(0.1)
# when excepts, check process died
except OSError as e:
e = str(e)
if e.find("No such process") > 0:
if os.path.exists(self.pidfile):
os.remove(self.pidfile)
else:
print("Error killing process, {}".format(e))
sys.exit(1)
def restart(self):
self.stop()
self.start()
def run(self, logger):
bot = Bot(logger)
if not bot.error:
bot.run()