diff --git a/releasenotes/notes/timer-optimization-a6babecaf1c7dab8.yaml b/releasenotes/notes/timer-optimization-a6babecaf1c7dab8.yaml new file mode 100644 index 0000000000..d039664354 --- /dev/null +++ b/releasenotes/notes/timer-optimization-a6babecaf1c7dab8.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + The timer trigger does not enqueue an event for every branch of every + project anymore and it now only processes projects actually using the + pipeline triggered by a timer. diff --git a/tests/fixtures/layouts/timer.yaml b/tests/fixtures/layouts/timer.yaml index e9e9a170db..5aaa4ce9a5 100644 --- a/tests/fixtures/layouts/timer.yaml +++ b/tests/fixtures/layouts/timer.yaml @@ -39,6 +39,12 @@ label: ubuntu-xenial run: playbooks/project-bitrot.yaml +- project: + name: org/project1 + check: + jobs: + - project-test1 + - project: name: org/project check: diff --git a/tests/unit/test_scheduler.py b/tests/unit/test_scheduler.py index 15f1ab0e32..158141b8d5 100755 --- a/tests/unit/test_scheduler.py +++ b/tests/unit/test_scheduler.py @@ -3375,6 +3375,18 @@ class TestScheduler(ZuulTestCase): self.assertEqual(len(self.builds), 2) + merge_count_project1 = 0 + for job in self.gearman_server.jobs_history: + if job.name == b'merger:refstate': + args = job.arguments + if isinstance(args, bytes): + args = args.decode('utf-8') + args = json.loads(args) + if args["items"][0]["project"] == "org/project1": + merge_count_project1 += 1 + self.assertEquals(merge_count_project1, 0, + "project1 shouldn't have any refstate call") + self.executor_server.hold_jobs_in_build = False # Stop queuing timer triggered jobs so that the assertions # below don't race against more jobs being queued. diff --git a/zuul/driver/timer/__init__.py b/zuul/driver/timer/__init__.py index 69cd508746..f3273425d1 100644 --- a/zuul/driver/timer/__init__.py +++ b/zuul/driver/timer/__init__.py @@ -79,7 +79,13 @@ class TimerDriver(Driver, TriggerInterface): jobs.append(job) def _onTrigger(self, tenant, pipeline_name, timespec): - for project_name in tenant.layout.project_configs.keys(): + for project_name, pcs in tenant.layout.project_configs.items(): + # timer operates on branch heads and doesn't need speculative + # layouts to decide if it should be enqueued or not. + # So it can be decided on cached data if it needs to run or not. + if not [True for pc in pcs if pipeline_name in pc.pipelines]: + continue + (trusted, project) = tenant.getProject(project_name) for branch in project.source.getProjectBranches(project, tenant): event = TimerTriggerEvent()