From 22aa3110d59ac01454ae1cecefc59213245845f3 Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Tue, 12 Jun 2018 22:43:39 -0500 Subject: [PATCH] + now exit in new daemon on command + no exit in new daemon on api crash --- onionr/communicator2.py | 55 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/onionr/communicator2.py b/onionr/communicator2.py index dc5140b2..a27591f4 100755 --- a/onionr/communicator2.py +++ b/onionr/communicator2.py @@ -19,7 +19,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . ''' -import sys, core, config, onionrblockapi as block, requests, time, logger +import sys, core, config, onionrblockapi as block, requests, time, logger, threading from defusedxml import minidom class OnionrCommunicatorDaemon: @@ -30,27 +30,70 @@ class OnionrCommunicatorDaemon: self.powSalt = 0 self.delay = 1 - OnionrCommunicatorTimers(self.timers, self.heartbeat, 1) + self.shutdown = False + + # Clear the daemon queue for any dead messages + self._core.clearDaemonQueue() - while True: + if debug or developmentMode: + OnionrCommunicatorTimers(self, self.heartbeat, 10) + + OnionrCommunicatorTimers(self, self.daemonCommands, 5) + OnionrCommunicatorTimers(self, self.detectAPICrash, 5) + + # Main daemon loop, mainly for calling timers, do not do any complex operations here + while not self.shutdown: time.sleep(self.delay) for i in self.timers: i.processTimer() + logger.info('Goodbye.') + def heartbeat(self): + '''Show a heartbeat debug message''' logger.debug('Communicator heartbeat') + def daemonCommands(self): + '''process daemon commands from daemonQueue''' + cmd = self._core.daemonQueue() + + if cmd is not False: + if cmd[0] == 'shutdown': + self.shutdown = True + else: + logger.info('Recieved daemonQueue command:' + cmd[0]) + + def detectAPICrash(self): + '''exit if the api server crashes/stops''' + if self._core._utils.localCommand('ping') != 'pong': + for i in range(4): + if self._core._utils.localCommand('ping') == 'pong': + break # break for loop + time.sleep(1) + else: + # This executes if the api is NOT detected to be running + logger.error('Daemon detected API crash (or otherwise unable to reach API after long time), stopping...') + self.shutdown = True + class OnionrCommunicatorTimers: - def __init__(self, timerList, timerFunction, frequency): + def __init__(self, daemonInstance, timerFunction, frequency, makeThread=True, threadAmount=1): self.timerFunction = timerFunction self.frequency = frequency + self.threadAmount = threadAmount + self.makeThread = makeThread + self.daemonInstance = daemonInstance + self._core = self.daemonInstance._core - timerList.append(self) + self.daemonInstance.timers.append(self) self.count = 0 def processTimer(self): self.count += 1 if self.count == self.frequency: - self.timerFunction() + if self.makeThread: + for i in range(self.threadAmount): + threading.Thread(target=self.timerFunction).run() + else: + self.timerFunction() self.count = 0