|
@@ -5,10 +5,13 @@ import threading
|
|
|
|
|
|
# from concurrent.futures import ThreadPoolExecutor
|
|
|
from pycs import app
|
|
|
-from eventlet import tpool
|
|
|
|
|
|
class GreenWorker(abc.ABC):
|
|
|
+ STOP_QUEUE = True
|
|
|
+ CONTINUE_QUEUE = False
|
|
|
+
|
|
|
def __init__(self):
|
|
|
+
|
|
|
super(GreenWorker, self).__init__()
|
|
|
|
|
|
self.pool = eventlet.GreenPool()
|
|
@@ -21,12 +24,15 @@ class GreenWorker(abc.ABC):
|
|
|
self.__running = False
|
|
|
|
|
|
|
|
|
+ @property
|
|
|
+ def ident(self):
|
|
|
+ return threading.get_ident()
|
|
|
+
|
|
|
|
|
|
def start(self):
|
|
|
if self.__running:
|
|
|
return
|
|
|
- # self._thread = self.pool.
|
|
|
- eventlet.spawn(self.__run__)
|
|
|
+ self._thread = self.pool.spawn_n(self.__run__)
|
|
|
self.__running = True
|
|
|
|
|
|
def stop(self):
|
|
@@ -50,52 +56,73 @@ class GreenWorker(abc.ABC):
|
|
|
eventlet.sleep(self.__sleep_time)
|
|
|
continue
|
|
|
|
|
|
+ def __log(self, log_func, msg):
|
|
|
+ log_func(f"[{self.ident}] {self.__class__.__name__}: {msg}")
|
|
|
+
|
|
|
+ def debug(self, msg):
|
|
|
+ self.__log(app.logger.debug, msg)
|
|
|
+
|
|
|
+ def info(self, msg):
|
|
|
+ self.__log(app.logger.info, msg)
|
|
|
+
|
|
|
+ def error(self, msg):
|
|
|
+ self.__log(app.logger.error, msg)
|
|
|
+
|
|
|
+ def warning(self, msg):
|
|
|
+ self.__log(app.logger.warning, msg)
|
|
|
+
|
|
|
+ def check_stop_event(self):
|
|
|
+ if self.stop_event.ready() and \
|
|
|
+ self.stop_event.wait(self.__sleep_time):
|
|
|
+
|
|
|
+ self.debug("Stop event received.")
|
|
|
+ self.stop_event.reset()
|
|
|
+ return True
|
|
|
+
|
|
|
+ eventlet.sleep(self.__sleep_time)
|
|
|
+ self.debug(f"No stop event received. Waiting for {self.__sleep_time} seconds.")
|
|
|
+ return False
|
|
|
+
|
|
|
+ def check_queue(self):
|
|
|
+ if self.queue.empty():
|
|
|
+ self.debug("Queue was empty, checking for stop...")
|
|
|
+ return self.STOP_QUEUE if self.check_stop_event() else self.CONTINUE_QUEUE
|
|
|
+
|
|
|
+ return self.queue.get(block=True)
|
|
|
+
|
|
|
+
|
|
|
def __run__(self):
|
|
|
while True:
|
|
|
- if self.queue.empty():
|
|
|
- # print("Queue was empty, checking for stop")
|
|
|
- if self.stop_event.ready() and \
|
|
|
- self.stop_event.wait(self.__sleep_time):
|
|
|
- # print("Stop event received")
|
|
|
- self.stop_event.reset()
|
|
|
- break
|
|
|
- else:
|
|
|
- eventlet.sleep(self.__sleep_time)
|
|
|
- # print("no stop event received")
|
|
|
- continue
|
|
|
-
|
|
|
- app.logger.info(f"starting job in thread #{self.ident}...")
|
|
|
- args = self.queue.get(block=True)
|
|
|
-
|
|
|
- self.start_work(*args)
|
|
|
-
|
|
|
- app.logger.info(f"pool #{self.ident} sending finish event...")
|
|
|
- # if not self.pool_finished.has_result():
|
|
|
- self.pool_finished.send(threading.get_ident())
|
|
|
+ res = self.check_queue()
|
|
|
+ if res is self.STOP_QUEUE:
|
|
|
+ break
|
|
|
|
|
|
- def start_work(self, *args):
|
|
|
- app.logger.info(f"[{self.__class__.__name__} - {self.ident}] starting work")
|
|
|
+ elif res is self.CONTINUE_QUEUE:
|
|
|
+ continue
|
|
|
|
|
|
- try:
|
|
|
- return tpool.execute(self.work, *args)
|
|
|
+ self.info(f"Got a job from the chache queue")
|
|
|
+ try:
|
|
|
+ self.info("Starting work")
|
|
|
+ self.start_work(*res)
|
|
|
+ except Exception as e:
|
|
|
+ self.error(f"Error occurred: {e}")
|
|
|
|
|
|
- except Exception as e:
|
|
|
- app.logger.error(f"[{self.__class__.__name__} - {self.ident}] error occurred: {e}")
|
|
|
+ finally:
|
|
|
+ self.info(f"Work finished")
|
|
|
|
|
|
- finally:
|
|
|
- app.logger.info(f"[{self.__class__.__name__} - {self.ident}] work finished")
|
|
|
+ self._finish()
|
|
|
|
|
|
- @property
|
|
|
- def ident(self):
|
|
|
- return threading.get_ident()
|
|
|
+ def _finish(self):
|
|
|
+ self.info("Sending finish event")
|
|
|
+ # if not self.pool_finished.has_result():
|
|
|
+ self.pool_finished.send(threading.get_ident())
|
|
|
|
|
|
+ def start_work(self, *args):
|
|
|
+ return eventlet.tpool.execute(self.work, *args)
|
|
|
|
|
|
- @abc.abstractmethod
|
|
|
def work(self, *args):
|
|
|
pass
|
|
|
|
|
|
-
|
|
|
-
|
|
|
if __name__ == '__main__':
|
|
|
import _thread as thread
|
|
|
class Foo(GreenWorker):
|