From 5241b883711a1d1eb864fd746b84e634c75d26f1 Mon Sep 17 00:00:00 2001 From: "James E. Blair" Date: Thu, 2 Apr 2015 14:56:35 -0700 Subject: Delay Gerrit events by 5s When querying a change immediately after a patchset upload, Gerrit may return incorrect data about dependent changes. In order to avoid this, ensure at least 5 seconds have elapsed before delivering any Gerrit events to Zuul. Change-Id: I95c459f52562556ca1722878e32388d51033e86c --- tests/base.py | 3 ++- zuul/lib/gerrit.py | 2 +- zuul/trigger/gerrit.py | 13 +++++++++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/tests/base.py b/tests/base.py index 08b3cab41..cd87b243a 100755 --- a/tests/base.py +++ b/tests/base.py @@ -396,7 +396,7 @@ class FakeGerrit(object): return c def addEvent(self, data): - return self.event_queue.put(data) + return self.event_queue.put((time.time(), data)) def getEvent(self): return self.event_queue.get() @@ -479,6 +479,7 @@ class FakeGerritTrigger(zuul.trigger.gerrit.Gerrit): def __init__(self, upstream_root, *args): super(FakeGerritTrigger, self).__init__(*args) self.upstream_root = upstream_root + self.gerrit_connector.delay = 0.0 def getGitUrl(self, project): return os.path.join(self.upstream_root, project.name) diff --git a/zuul/lib/gerrit.py b/zuul/lib/gerrit.py index 9aeff3df8..6c7906bd2 100644 --- a/zuul/lib/gerrit.py +++ b/zuul/lib/gerrit.py @@ -39,7 +39,7 @@ class GerritWatcher(threading.Thread): data = json.loads(l) self.log.debug("Received data from Gerrit event stream: \n%s" % pprint.pformat(data)) - self.gerrit.addEvent(data) + self.gerrit.addEvent((time.time(), data)) def _listen(self, stdout, stderr): poll = select.poll() diff --git a/zuul/trigger/gerrit.py b/zuul/trigger/gerrit.py index 7d970ad1c..a99db4d1f 100644 --- a/zuul/trigger/gerrit.py +++ b/zuul/trigger/gerrit.py @@ -26,6 +26,7 @@ class GerritEventConnector(threading.Thread): """Move events from Gerrit to the scheduler.""" log = logging.getLogger("zuul.GerritEventConnector") + delay = 5.0 def __init__(self, gerrit, sched, trigger): super(GerritEventConnector, self).__init__() @@ -37,12 +38,20 @@ class GerritEventConnector(threading.Thread): def stop(self): self._stopped = True - self.gerrit.addEvent(None) + self.gerrit.addEvent((None, None)) def _handleEvent(self): - data = self.gerrit.getEvent() + ts, data = self.gerrit.getEvent() if self._stopped: return + # Gerrit can produce inconsistent data immediately after an + # event, So ensure that we do not deliver the event to Zuul + # until at least a certain amount of time has passed. Note + # that if we receive several events in succession, we will + # only need to delay for the first event. In essence, Zuul + # should always be a constant number of seconds behind Gerrit. + now = time.time() + time.sleep(max((ts + self.delay) - now, 0.0)) event = TriggerEvent() event.type = data.get('type') event.trigger_name = self.trigger.name -- cgit v1.2.1