Only emit parent-change-enqueued if needed

When running with GitHub and many app installations emitting the
parent-change-enqueued event is very expensive. In most cases this
event will be used to enqueue downstream changes together with the
parent change into a gate queue. Currently this event is emitted if
any pipeline uses defined trigger regardless if the event will be
consumed or not.

Emitting this event only when there is a real user makes it possible
to use this event in the gate pipeline without overloading github by
depends-on search requests triggered by items enqueued into the check
pipeline.

Change-Id: Iadcfe9b96172dcc3d0affb252a542beed3b90831
This commit is contained in:
Tobias Henkel 2018-04-20 18:44:00 +02:00
parent 623533ab85
commit 1dbb3ccabc
2 changed files with 40 additions and 8 deletions

View File

@ -15,6 +15,7 @@
# under the License.
from tests.base import ZuulTestCase
from zuul.driver.zuul.zuulmodel import ZuulTriggerEvent
class TestZuulTriggerParentChangeEnqueued(ZuulTestCase):
@ -61,6 +62,32 @@ class TestZuulTriggerParentChangeEnqueued(ZuulTestCase):
else:
raise Exception("Unknown job")
# Now directly enqueue a change into the check. As no pipeline reacts
# on parent-change-enqueued from pipeline check no
# parent-change-enqueued event is expected.
zuultrigger_event_count = 0
def counting_put(*args, **kwargs):
nonlocal zuultrigger_event_count
if isinstance(args[0], ZuulTriggerEvent):
zuultrigger_event_count += 1
self.sched.trigger_event_queue.put_orig(*args, **kwargs)
self.sched.trigger_event_queue.put_orig = \
self.sched.trigger_event_queue.put
self.sched.trigger_event_queue.put = counting_put
C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
C.addApproval('Verified', -1)
D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
D.addApproval('Verified', -1)
D.setDependsOn(C, 1)
self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
self.waitUntilSettled()
self.assertEqual(len(self.history), 4)
self.assertEqual(zuultrigger_event_count, 0)
class TestZuulTriggerProjectChangeMerged(ZuulTestCase):

View File

@ -28,26 +28,29 @@ class ZuulDriver(Driver, TriggerInterface):
log = logging.getLogger("zuul.ZuulTrigger")
def __init__(self):
self.tenant_events = {}
self.parent_change_enqueued_events = {}
self.project_change_merged_events = {}
def registerScheduler(self, scheduler):
self.sched = scheduler
def reconfigure(self, tenant):
events = set()
self.tenant_events[tenant.name] = events
for pipeline in tenant.layout.pipelines.values():
for ef in pipeline.manager.event_filters:
if not isinstance(ef.trigger, zuultrigger.ZuulTrigger):
continue
if PARENT_CHANGE_ENQUEUED in ef._types:
events.add(PARENT_CHANGE_ENQUEUED)
# parent-change-enqueued events need to be filtered by
# pipeline
for pipeline in ef._pipelines:
key = (tenant.name, pipeline)
self.parent_change_enqueued_events[key] = True
elif PROJECT_CHANGE_MERGED in ef._types:
events.add(PROJECT_CHANGE_MERGED)
self.project_change_merged_events[tenant.name] = True
def onChangeMerged(self, tenant, change, source):
# Called each time zuul merges a change
if PROJECT_CHANGE_MERGED in self.tenant_events[tenant.name]:
if self.project_change_merged_events.get(tenant.name):
try:
self._createProjectChangeMergedEvents(change, source)
except Exception:
@ -56,9 +59,11 @@ class ZuulDriver(Driver, TriggerInterface):
"%s" % (change,))
def onChangeEnqueued(self, tenant, change, pipeline):
self.log.debug("onChangeEnqueued %s", self.tenant_events[tenant.name])
# Called each time a change is enqueued in a pipeline
if PARENT_CHANGE_ENQUEUED in self.tenant_events[tenant.name]:
tenant_events = self.parent_change_enqueued_events.get(
(tenant.name, pipeline.name))
self.log.debug("onChangeEnqueued %s", tenant_events)
if tenant_events:
try:
self._createParentChangeEnqueuedEvents(change, pipeline)
except Exception: