From 0388568ea0516afba2e44784540c9c389d96dcf9 Mon Sep 17 00:00:00 2001 From: Mike McMahon Date: Thu, 7 Sep 2017 13:41:43 -0700 Subject: [PATCH 1/4] Reduces the job to only looking at objects older than the cutoff date Signed-off-by: Mike McMahon --- awx/main/management/commands/cleanup_jobs.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/awx/main/management/commands/cleanup_jobs.py b/awx/main/management/commands/cleanup_jobs.py index cb03e4e9d6..d58ffb97c3 100644 --- a/awx/main/management/commands/cleanup_jobs.py +++ b/awx/main/management/commands/cleanup_jobs.py @@ -87,7 +87,8 @@ class Command(NoArgsCommand): def cleanup_ad_hoc_commands(self): skipped, deleted = 0, 0 - for ad_hoc_command in AdHocCommand.objects.all(): + ad_hoc_commands = AdHocCommand.objects.filter(created__lte=self.cutoff) + for ad_hoc_command in ad_hoc_commands: ad_hoc_command_display = '"%s" (%d events)' % \ (unicode(ad_hoc_command), ad_hoc_command.ad_hoc_command_events.count()) @@ -109,7 +110,8 @@ class Command(NoArgsCommand): def cleanup_project_updates(self): skipped, deleted = 0, 0 - for pu in ProjectUpdate.objects.all(): + project_updates = ProjectUpdate.objects.filter(created__lte=self.cutoff) + for pu in project_updates pu_display = '"%s" (type %s)' % (unicode(pu), unicode(pu.launch_type)) if pu.status in ('pending', 'waiting', 'running'): action_text = 'would skip' if self.dry_run else 'skipping' @@ -133,6 +135,7 @@ class Command(NoArgsCommand): def cleanup_inventory_updates(self): skipped, deleted = 0, 0 + inventory_updates = InventoryUpdate.objects.filter(created__lte=self.cutoff) for iu in InventoryUpdate.objects.all(): iu_display = '"%s" (source %s)' % (unicode(iu), unicode(iu.source)) if iu.status in ('pending', 'waiting', 'running'): @@ -157,7 +160,8 @@ class Command(NoArgsCommand): def cleanup_management_jobs(self): skipped, deleted = 0, 0 - for sj in SystemJob.objects.all(): + system_jobs = SystemJob.objects.filter(created__lte=self.cutoff) + for sj in system_jobs: sj_display = '"%s" (type %s)' % (unicode(sj), unicode(sj.job_type)) if sj.status in ('pending', 'waiting', 'running'): action_text = 'would skip' if self.dry_run else 'skipping' @@ -187,7 +191,8 @@ class Command(NoArgsCommand): def cleanup_workflow_jobs(self): skipped, deleted = 0, 0 - for workflow_job in WorkflowJob.objects.all(): + workflow_jobs = WorkflowJob.objects.filter(created__lte=self.cutoff) + for workflow_job in workflow_jobs: workflow_job_display = '"{}" ({} nodes)'.format( unicode(workflow_job), workflow_job.workflow_nodes.count()) @@ -209,7 +214,8 @@ class Command(NoArgsCommand): def cleanup_notifications(self): skipped, deleted = 0, 0 - for notification in Notification.objects.all(): + notifications = Notification.objects.filter(created__lte=self.cutoff) + for notification in notifications: notification_display = '"{}" (started {}, {} type, {} sent)'.format( unicode(notification), unicode(notification.created), notification.notification_type, notification.notifications_sent) @@ -255,3 +261,4 @@ class Command(NoArgsCommand): self.logger.log(99, '%s: %d would be deleted, %d would be skipped.', m.replace('_', ' '), deleted, skipped) else: self.logger.log(99, '%s: %d deleted, %d skipped.', m.replace('_', ' '), deleted, skipped) + From 023431165a851b6e0df8200716d8dea405c30367 Mon Sep 17 00:00:00 2001 From: Mike McMahon Date: Thu, 7 Sep 2017 14:03:18 -0700 Subject: [PATCH 2/4] fixing missing colon and missing variable usage Signed-off-by: Mike McMahon --- awx/main/management/commands/cleanup_jobs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/awx/main/management/commands/cleanup_jobs.py b/awx/main/management/commands/cleanup_jobs.py index d58ffb97c3..cc621e2b23 100644 --- a/awx/main/management/commands/cleanup_jobs.py +++ b/awx/main/management/commands/cleanup_jobs.py @@ -111,7 +111,7 @@ class Command(NoArgsCommand): def cleanup_project_updates(self): skipped, deleted = 0, 0 project_updates = ProjectUpdate.objects.filter(created__lte=self.cutoff) - for pu in project_updates + for pu in project_updates: pu_display = '"%s" (type %s)' % (unicode(pu), unicode(pu.launch_type)) if pu.status in ('pending', 'waiting', 'running'): action_text = 'would skip' if self.dry_run else 'skipping' @@ -136,7 +136,7 @@ class Command(NoArgsCommand): def cleanup_inventory_updates(self): skipped, deleted = 0, 0 inventory_updates = InventoryUpdate.objects.filter(created__lte=self.cutoff) - for iu in InventoryUpdate.objects.all(): + for iu in inventory_updates: iu_display = '"%s" (source %s)' % (unicode(iu), unicode(iu.source)) if iu.status in ('pending', 'waiting', 'running'): action_text = 'would skip' if self.dry_run else 'skipping' From 399e0e5e24cd083c1799518f7c81565e6ff5065b Mon Sep 17 00:00:00 2001 From: Mike McMahon Date: Fri, 8 Sep 2017 18:37:59 -0700 Subject: [PATCH 3/4] switching to iterator and adding the missed Job cleanup Signed-off-by: Mike McMahon --- awx/main/management/commands/cleanup_jobs.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/awx/main/management/commands/cleanup_jobs.py b/awx/main/management/commands/cleanup_jobs.py index cc621e2b23..3e45cec3cd 100644 --- a/awx/main/management/commands/cleanup_jobs.py +++ b/awx/main/management/commands/cleanup_jobs.py @@ -65,7 +65,8 @@ class Command(NoArgsCommand): #jobs_qs = Job.objects.exclude(status__in=('pending', 'running')) #jobs_qs = jobs_qs.filter(created__lte=self.cutoff) skipped, deleted = 0, 0 - for job in Job.objects.all(): + jobs = Job.objects.filter(created__lte=self.cutoff) + for job in jobs.iterator(): job_display = '"%s" (%d host summaries, %d events)' % \ (unicode(job), job.job_host_summaries.count(), job.job_events.count()) @@ -88,7 +89,7 @@ class Command(NoArgsCommand): def cleanup_ad_hoc_commands(self): skipped, deleted = 0, 0 ad_hoc_commands = AdHocCommand.objects.filter(created__lte=self.cutoff) - for ad_hoc_command in ad_hoc_commands: + for ad_hoc_command in ad_hoc_commands.iterator(): ad_hoc_command_display = '"%s" (%d events)' % \ (unicode(ad_hoc_command), ad_hoc_command.ad_hoc_command_events.count()) @@ -111,7 +112,7 @@ class Command(NoArgsCommand): def cleanup_project_updates(self): skipped, deleted = 0, 0 project_updates = ProjectUpdate.objects.filter(created__lte=self.cutoff) - for pu in project_updates: + for pu in project_updates.iterator(): pu_display = '"%s" (type %s)' % (unicode(pu), unicode(pu.launch_type)) if pu.status in ('pending', 'waiting', 'running'): action_text = 'would skip' if self.dry_run else 'skipping' @@ -136,7 +137,7 @@ class Command(NoArgsCommand): def cleanup_inventory_updates(self): skipped, deleted = 0, 0 inventory_updates = InventoryUpdate.objects.filter(created__lte=self.cutoff) - for iu in inventory_updates: + for iu in inventory_updates.iterator(): iu_display = '"%s" (source %s)' % (unicode(iu), unicode(iu.source)) if iu.status in ('pending', 'waiting', 'running'): action_text = 'would skip' if self.dry_run else 'skipping' @@ -161,7 +162,7 @@ class Command(NoArgsCommand): def cleanup_management_jobs(self): skipped, deleted = 0, 0 system_jobs = SystemJob.objects.filter(created__lte=self.cutoff) - for sj in system_jobs: + for sj in system_jobs.iterator(): sj_display = '"%s" (type %s)' % (unicode(sj), unicode(sj.job_type)) if sj.status in ('pending', 'waiting', 'running'): action_text = 'would skip' if self.dry_run else 'skipping' @@ -192,7 +193,7 @@ class Command(NoArgsCommand): def cleanup_workflow_jobs(self): skipped, deleted = 0, 0 workflow_jobs = WorkflowJob.objects.filter(created__lte=self.cutoff) - for workflow_job in workflow_jobs: + for workflow_job in workflow_jobs.iterator(): workflow_job_display = '"{}" ({} nodes)'.format( unicode(workflow_job), workflow_job.workflow_nodes.count()) @@ -215,7 +216,7 @@ class Command(NoArgsCommand): def cleanup_notifications(self): skipped, deleted = 0, 0 notifications = Notification.objects.filter(created__lte=self.cutoff) - for notification in notifications: + for notification in notifications.iterator(): notification_display = '"{}" (started {}, {} type, {} sent)'.format( unicode(notification), unicode(notification.created), notification.notification_type, notification.notifications_sent) From 0cd34c14982b1ab1b8f9f25ca2a2c7b873353767 Mon Sep 17 00:00:00 2001 From: Mike McMahon Date: Fri, 8 Sep 2017 18:46:52 -0700 Subject: [PATCH 4/4] jobs take count of gte cutoff, process only lt cutoff Signed-off-by: Mike McMahon --- awx/main/management/commands/cleanup_jobs.py | 56 ++++++++------------ 1 file changed, 21 insertions(+), 35 deletions(-) diff --git a/awx/main/management/commands/cleanup_jobs.py b/awx/main/management/commands/cleanup_jobs.py index 3e45cec3cd..fb2634da4d 100644 --- a/awx/main/management/commands/cleanup_jobs.py +++ b/awx/main/management/commands/cleanup_jobs.py @@ -65,7 +65,7 @@ class Command(NoArgsCommand): #jobs_qs = Job.objects.exclude(status__in=('pending', 'running')) #jobs_qs = jobs_qs.filter(created__lte=self.cutoff) skipped, deleted = 0, 0 - jobs = Job.objects.filter(created__lte=self.cutoff) + jobs = Job.objects.filter(created__lt=self.cutoff) for job in jobs.iterator(): job_display = '"%s" (%d host summaries, %d events)' % \ (unicode(job), @@ -74,21 +74,19 @@ class Command(NoArgsCommand): action_text = 'would skip' if self.dry_run else 'skipping' self.logger.debug('%s %s job %s', action_text, job.status, job_display) skipped += 1 - elif job.created >= self.cutoff: - action_text = 'would skip' if self.dry_run else 'skipping' - self.logger.debug('%s %s', action_text, job_display) - skipped += 1 else: action_text = 'would delete' if self.dry_run else 'deleting' self.logger.info('%s %s', action_text, job_display) if not self.dry_run: job.delete() deleted += 1 + + skipped += Job.objects.filter(created__gte=self.cutoff).count() return skipped, deleted def cleanup_ad_hoc_commands(self): skipped, deleted = 0, 0 - ad_hoc_commands = AdHocCommand.objects.filter(created__lte=self.cutoff) + ad_hoc_commands = AdHocCommand.objects.filter(created__lt=self.cutoff) for ad_hoc_command in ad_hoc_commands.iterator(): ad_hoc_command_display = '"%s" (%d events)' % \ (unicode(ad_hoc_command), @@ -97,21 +95,19 @@ class Command(NoArgsCommand): action_text = 'would skip' if self.dry_run else 'skipping' self.logger.debug('%s %s ad hoc command %s', action_text, ad_hoc_command.status, ad_hoc_command_display) skipped += 1 - elif ad_hoc_command.created >= self.cutoff: - action_text = 'would skip' if self.dry_run else 'skipping' - self.logger.debug('%s %s', action_text, ad_hoc_command_display) - skipped += 1 else: action_text = 'would delete' if self.dry_run else 'deleting' self.logger.info('%s %s', action_text, ad_hoc_command_display) if not self.dry_run: ad_hoc_command.delete() deleted += 1 + + skipped += AdHocCommand.objects.filter(created__gte=self.cutoff).count() return skipped, deleted def cleanup_project_updates(self): skipped, deleted = 0, 0 - project_updates = ProjectUpdate.objects.filter(created__lte=self.cutoff) + project_updates = ProjectUpdate.objects.filter(created__lt=self.cutoff) for pu in project_updates.iterator(): pu_display = '"%s" (type %s)' % (unicode(pu), unicode(pu.launch_type)) if pu.status in ('pending', 'waiting', 'running'): @@ -122,21 +118,19 @@ class Command(NoArgsCommand): action_text = 'would skip' if self.dry_run else 'skipping' self.logger.debug('%s %s', action_text, pu_display) skipped += 1 - elif pu.created >= self.cutoff: - action_text = 'would skip' if self.dry_run else 'skipping' - self.logger.debug('%s %s', action_text, pu_display) - skipped += 1 else: action_text = 'would delete' if self.dry_run else 'deleting' self.logger.info('%s %s', action_text, pu_display) if not self.dry_run: pu.delete() deleted += 1 + + skipped += ProjectUpdate.objects.filter(created__gte=self.cutoff).count() return skipped, deleted def cleanup_inventory_updates(self): skipped, deleted = 0, 0 - inventory_updates = InventoryUpdate.objects.filter(created__lte=self.cutoff) + inventory_updates = InventoryUpdate.objects.filter(created__lt=self.cutoff) for iu in inventory_updates.iterator(): iu_display = '"%s" (source %s)' % (unicode(iu), unicode(iu.source)) if iu.status in ('pending', 'waiting', 'running'): @@ -147,37 +141,33 @@ class Command(NoArgsCommand): action_text = 'would skip' if self.dry_run else 'skipping' self.logger.debug('%s %s', action_text, iu_display) skipped += 1 - elif iu.created >= self.cutoff: - action_text = 'would skip' if self.dry_run else 'skipping' - self.logger.debug('%s %s', action_text, iu_display) - skipped += 1 else: action_text = 'would delete' if self.dry_run else 'deleting' self.logger.info('%s %s', action_text, iu_display) if not self.dry_run: iu.delete() deleted += 1 + + skipped += InventoryUpdate.objects.filter(created__gte=self.cutoff).count() return skipped, deleted def cleanup_management_jobs(self): skipped, deleted = 0, 0 - system_jobs = SystemJob.objects.filter(created__lte=self.cutoff) + system_jobs = SystemJob.objects.filter(created__lt=self.cutoff) for sj in system_jobs.iterator(): sj_display = '"%s" (type %s)' % (unicode(sj), unicode(sj.job_type)) if sj.status in ('pending', 'waiting', 'running'): action_text = 'would skip' if self.dry_run else 'skipping' self.logger.debug('%s %s system_job %s', action_text, sj.status, sj_display) skipped += 1 - elif sj.created >= self.cutoff: - action_text = 'would skip' if self.dry_run else 'skipping' - self.logger.debug('%s %s', action_text, sj_display) - skipped += 1 else: action_text = 'would delete' if self.dry_run else 'deleting' self.logger.info('%s %s', action_text, sj_display) if not self.dry_run: sj.delete() deleted += 1 + + skipped += SystemJob.objects.filter(created__gte=self.cutoff).count() return skipped, deleted def init_logging(self): @@ -192,7 +182,7 @@ class Command(NoArgsCommand): def cleanup_workflow_jobs(self): skipped, deleted = 0, 0 - workflow_jobs = WorkflowJob.objects.filter(created__lte=self.cutoff) + workflow_jobs = WorkflowJob.objects.filter(created__lt=self.cutoff) for workflow_job in workflow_jobs.iterator(): workflow_job_display = '"{}" ({} nodes)'.format( unicode(workflow_job), @@ -201,21 +191,19 @@ class Command(NoArgsCommand): action_text = 'would skip' if self.dry_run else 'skipping' self.logger.debug('%s %s job %s', action_text, workflow_job.status, workflow_job_display) skipped += 1 - elif workflow_job.created >= self.cutoff: - action_text = 'would skip' if self.dry_run else 'skipping' - self.logger.debug('%s %s', action_text, workflow_job_display) - skipped += 1 else: action_text = 'would delete' if self.dry_run else 'deleting' self.logger.info('%s %s', action_text, workflow_job_display) if not self.dry_run: workflow_job.delete() deleted += 1 + + skipped += WorkflowJob.objects.filter(created__gte=self.cutoff).count() return skipped, deleted def cleanup_notifications(self): skipped, deleted = 0, 0 - notifications = Notification.objects.filter(created__lte=self.cutoff) + notifications = Notification.objects.filter(created__lt=self.cutoff) for notification in notifications.iterator(): notification_display = '"{}" (started {}, {} type, {} sent)'.format( unicode(notification), unicode(notification.created), @@ -224,16 +212,14 @@ class Command(NoArgsCommand): action_text = 'would skip' if self.dry_run else 'skipping' self.logger.debug('%s %s notification %s', action_text, notification.status, notification_display) skipped += 1 - elif notification.created >= self.cutoff: - action_text = 'would skip' if self.dry_run else 'skipping' - self.logger.debug('%s %s', action_text, notification_display) - skipped += 1 else: action_text = 'would delete' if self.dry_run else 'deleting' self.logger.info('%s %s', action_text, notification_display) if not self.dry_run: notification.delete() deleted += 1 + + skipped += Notification.objects.filter(created__gte=self.cutoff).count() return skipped, deleted @transaction.atomic