| |
@@ -15,6 +15,7 @@
|
| |
from __future__ import absolute_import
|
| |
from functools import wraps
|
| |
import sched
|
| |
+ import threading
|
| |
import time
|
| |
|
| |
from module_build_service.common import log
|
| |
@@ -40,6 +41,10 @@
|
| |
are executed.
|
| |
"""
|
| |
|
| |
+ def __init__(self, *args, **kwargs):
|
| |
+ sched.scheduler.__init__(self, *args, **kwargs)
|
| |
+ self.local = threading.local()
|
| |
+
|
| |
def add(self, handler, arguments=()):
|
| |
"""
|
| |
Schedule execution of `handler` with `arguments`.
|
| |
@@ -50,10 +55,20 @@
|
| |
"""
|
| |
Runs scheduled handlers.
|
| |
"""
|
| |
- log.debug("Running event scheduler with following events:")
|
| |
- for event in self.queue:
|
| |
- log.debug(" %r", event)
|
| |
- sched.scheduler.run(self)
|
| |
+ if getattr(self.local, 'running', False):
|
| |
+ return
|
| |
+
|
| |
+ try:
|
| |
+ self.local.running = True
|
| |
+ # Note that events that are added during the execution of the
|
| |
+ # handlers are executed as part of the .run() call without
|
| |
+ # further logging.
|
| |
+ log.debug("Running event scheduler with following events:")
|
| |
+ for event in self.queue:
|
| |
+ log.debug(" %r", event)
|
| |
+ sched.scheduler.run(self)
|
| |
+ finally:
|
| |
+ self.local.running = False
|
| |
|
| |
def reset(self):
|
| |
"""
|
| |
Because each event handler wrapper would call scheduler.run() at the end before
returning, with a queue of 100 events to process we'd end up
with:
Event handler 1 wrapper
scheduler.run()
Event handler 2 wrapper
scheduler.run()
.....
.... Event handler 100 wrapper
Which would eventually exhaust the Python stack limit. Fix this by making scheduler.run()
no-op if the scheduler is already processing the queue in the current thread.