|
@@ -11,59 +11,7 @@ from celery import conf
|
|
|
from celery import log
|
|
|
|
|
|
|
|
|
-class BackgroundThread(threading.Thread):
|
|
|
- """Thread running an infinite loop which for every iteration
|
|
|
- calls its :meth:`on_iteration` method.
|
|
|
-
|
|
|
- This also implements graceful shutdown of the thread by providing
|
|
|
- the :meth:`stop` method.
|
|
|
-
|
|
|
- """
|
|
|
-
|
|
|
- def __init__(self):
|
|
|
- super(BackgroundThread, self).__init__()
|
|
|
- self._shutdown = threading.Event()
|
|
|
- self._stopped = threading.Event()
|
|
|
- self.setDaemon(True)
|
|
|
-
|
|
|
- def run(self):
|
|
|
- """This is the body of the thread.
|
|
|
-
|
|
|
- To start the thread use :meth:`start` instead.
|
|
|
-
|
|
|
- """
|
|
|
- self.on_start()
|
|
|
-
|
|
|
- while 1:
|
|
|
- if self._shutdown.isSet():
|
|
|
- break
|
|
|
- self.on_iteration()
|
|
|
- self._stopped.set() # indicate that we are stopped
|
|
|
-
|
|
|
- def on_start(self):
|
|
|
- """This handler is run at thread start, just before the infinite
|
|
|
- loop."""
|
|
|
- pass
|
|
|
-
|
|
|
- def on_iteration(self):
|
|
|
- """This is the method called for every iteration and must be
|
|
|
- implemented by every subclass of :class:`BackgroundThread`."""
|
|
|
- raise NotImplementedError(
|
|
|
- "InfiniteThreads must implement on_iteration")
|
|
|
-
|
|
|
- def on_stop(self):
|
|
|
- """This handler is run when the thread is shutdown."""
|
|
|
- pass
|
|
|
-
|
|
|
- def stop(self):
|
|
|
- """Gracefully shutdown the thread."""
|
|
|
- self.on_stop()
|
|
|
- self._shutdown.set()
|
|
|
- self._stopped.wait() # block until this thread is done
|
|
|
- self.join(1e100)
|
|
|
-
|
|
|
-
|
|
|
-class Mediator(BackgroundThread):
|
|
|
+class Mediator(threading.Thread):
|
|
|
"""Thread continuously sending tasks in the queue to the pool.
|
|
|
|
|
|
.. attribute:: ready_queue
|
|
@@ -78,13 +26,15 @@ class Mediator(BackgroundThread):
|
|
|
"""
|
|
|
|
|
|
def __init__(self, ready_queue, callback, logger=None):
|
|
|
- super(Mediator, self).__init__()
|
|
|
+ threading.Thread.__init__(self)
|
|
|
self.logger = logger or log.get_default_logger()
|
|
|
self.ready_queue = ready_queue
|
|
|
self.callback = callback
|
|
|
+ self._shutdown = threading.Event()
|
|
|
+ self._stopped = threading.Event()
|
|
|
+ self.setDaemon(True)
|
|
|
|
|
|
- def on_iteration(self):
|
|
|
- """Get tasks from bucket queue and apply the task callback."""
|
|
|
+ def move(self):
|
|
|
try:
|
|
|
# This blocks until there's a message in the queue.
|
|
|
task = self.ready_queue.get(timeout=1)
|
|
@@ -95,25 +45,17 @@ class Mediator(BackgroundThread):
|
|
|
return
|
|
|
|
|
|
self.logger.debug(
|
|
|
- "Mediator: Running callback for task: %s[%s]" % (
|
|
|
- task.task_name, task.task_id))
|
|
|
+ "Mediator: Running callback for task: %s[%s]" % (
|
|
|
+ task.task_name, task.task_id))
|
|
|
self.callback(task) # execute
|
|
|
|
|
|
+ def run(self):
|
|
|
+ while not self._shutdown.isSet():
|
|
|
+ self.move()
|
|
|
+ self._stopped.set() # indicate that we are stopped
|
|
|
|
|
|
-class ScheduleController(BackgroundThread):
|
|
|
- """Schedules tasks with an ETA by moving them to the bucket queue."""
|
|
|
-
|
|
|
- def __init__(self, eta_schedule, logger=None,
|
|
|
- precision=None):
|
|
|
- super(ScheduleController, self).__init__()
|
|
|
- self.logger = logger or log.get_default_logger()
|
|
|
- self._scheduler = iter(eta_schedule)
|
|
|
- self.precision = precision or conf.CELERYD_ETA_SCHEDULER_PRECISION
|
|
|
- self.debug = log.SilenceRepeated(self.logger.debug, max_iterations=10)
|
|
|
-
|
|
|
- def on_iteration(self):
|
|
|
- """Wake-up scheduler"""
|
|
|
- delay = self._scheduler.next()
|
|
|
- self.debug("ScheduleController: Scheduler wake-up"
|
|
|
- "ScheduleController: Next wake-up eta %s seconds..." % delay)
|
|
|
- time.sleep(delay or self.precision)
|
|
|
+ def stop(self):
|
|
|
+ """Gracefully shutdown the thread."""
|
|
|
+ self._shutdown.set()
|
|
|
+ self._stopped.wait() # block until this thread is done
|
|
|
+ self.join(1e100)
|