def run(self): redis_client = get_redis_client() existing_pid = redis_client.get(self.LOCK_NAME) if not redis_client.setnx(self.LOCK_NAME, os.getpid()): existing_pid = int(redis_client.get(self.LOCK_NAME)) try: os.kill(existing_pid, 0) except OSError: redis_client.set(self.LOCK_NAME, os.getpid()) else: logger.warning("Not starting as another instance detected.") sys.stderr.write("Already running\n") sys.exit(1) logger.info("Starting longliving process") try: threads = self.get_threads() for thread in threads: thread.start() logger.info("Longliving threads started") try: while not self.bail.isSet(): time.sleep(1) logger.info("Shutting down") except KeyboardInterrupt: logger.info("Caught KeyboardInterrupt; shutting down.") self.bail.set() redis_client.publish(LonglivingThread.BAIL_CHANNEL, '') for i in range(5): for thread in threads[:]: thread.join(5) if thread.isAlive(): frame = sys._current_frames()[thread.ident] try: logger.warning("Couldn't join thread %r on attempt %i/5:\n%s", thread.name, i + 1, ''.join(traceback.format_stack(frame))) finally: del frame else: threads.remove(thread) if threads: logger.error("Couldn't join all threads.") else: logger.info("All threads finished; stopping.") finally: redis_client.delete(self.LOCK_NAME)
def stop(self, signo=None, frame=None): self.bail.set() redis_client = get_redis_client() redis_client.publish(LonglivingThread.BAIL_CHANNEL, '')