summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClark Boylan <clark.boylan@gmail.com>2017-04-18 13:59:01 -0700
committerClark Boylan <clark.boylan@gmail.com>2017-04-25 10:13:14 -0700
commitfa651805412941df53c8ea2349d29e0241ace662 (patch)
treebe5d754b4cbe159459d9742c001d4d1247229fd8
parentafc49ea495cc2935f88c4a1458ceb669fe7f65a1 (diff)
downloadzuul-fa651805412941df53c8ea2349d29e0241ace662.tar.gz
Add ability to stop drivers
This adds an optional method to the driver interface that will stop a driver when the scheduler's connections object is stopped. This is useful to clean up drivers that have state that are not connections. In particular it prevents timers from leaking apscheduler threads all over the test suite. For defensive purposes we add code to start a new apsched within the driver if the driver has been previously stopped. This is because without having connection objects which can be replaced the driver may stay in use though it currently only stops when the scheduler stops. Change-Id: Ibfc638d88c77f18bdc9f9509776a665a9edfc2ae
-rw-r--r--zuul/driver/__init__.py11
-rw-r--r--zuul/driver/timer/__init__.py8
-rw-r--r--zuul/lib/connections.py2
3 files changed, 20 insertions, 1 deletions
diff --git a/zuul/driver/__init__.py b/zuul/driver/__init__.py
index 1cc5235fa..57b5cf9eb 100644
--- a/zuul/driver/__init__.py
+++ b/zuul/driver/__init__.py
@@ -68,6 +68,17 @@ class Driver(object):
"""
pass
+ def stop(self):
+ """Stop the driver from running.
+
+ This method is optional; the base implementation does nothing.
+
+ This method is called when the connection registry is stopped
+ allowing you additionally stop any running Driver computation
+ not specific to a connection.
+ """
+ pass
+
@six.add_metaclass(abc.ABCMeta)
class ConnectionInterface(object):
diff --git a/zuul/driver/timer/__init__.py b/zuul/driver/timer/__init__.py
index 00ddb26a3..115e6af43 100644
--- a/zuul/driver/timer/__init__.py
+++ b/zuul/driver/timer/__init__.py
@@ -38,6 +38,10 @@ class TimerDriver(Driver, TriggerInterface):
def reconfigure(self, tenant):
self._removeJobs(tenant)
+ if not self.apsched:
+ # Handle possible reuse of the driver without connection objects.
+ self.apsched = BackgroundScheduler()
+ self.apsched.start()
self._addJobs(tenant)
def _removeJobs(self, tenant):
@@ -87,7 +91,9 @@ class TimerDriver(Driver, TriggerInterface):
self.sched.addEvent(event)
def stop(self):
- self.apsched.shutdown()
+ if self.apsched:
+ self.apsched.shutdown()
+ self.apsched = None
def getTrigger(self, connection_name, config=None):
return timertrigger.TimerTrigger(self, config)
diff --git a/zuul/lib/connections.py b/zuul/lib/connections.py
index 262c7cbb8..03cba2af3 100644
--- a/zuul/lib/connections.py
+++ b/zuul/lib/connections.py
@@ -67,6 +67,8 @@ class ConnectionRegistry(object):
def stop(self):
for connection_name, connection in self.connections.items():
connection.onStop()
+ for driver in self.drivers.values():
+ driver.stop()
def configure(self, config):
# Register connections from the config