Skip to content

Commit 5e1a6b3

Browse files
committed
Merge pull request #7 from dabapps/delete-old-jobs
Management command to delete old jobs
2 parents 2345cae + d50a2fd commit 5e1a6b3

File tree

4 files changed

+56
-0
lines changed

4 files changed

+56
-0
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ Jobs have a `state` field which can have one of the following values:
109109

110110
#### Management commands
111111

112+
There is a management command, `manage.py delete_old_jobs`, which deletes any
113+
jobs from the database which are in state `COMPLETE` or `FAILED` and were
114+
created more than 24 hours ago. This could be run, for example, as a cron task,
115+
to ensure the jobs table remains at a reasonable size.
116+
112117
For debugging/development purposes, a simple management command is supplied to create jobs:
113118

114119
manage.py create_job <job_name> --queue_name 'my_queue_name' --workspace '{"key": "value"}'
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from django.core.management.base import BaseCommand
2+
from django_dbq.models import Job
3+
4+
5+
class Command(BaseCommand):
6+
7+
help = "Delete old jobs"
8+
9+
def handle(self, *args, **options):
10+
Job.objects.delete_old()
11+
self.stdout.write('Deleted old jobs')

django_dbq/models.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@
33
from django_dbq.tasks import get_next_task_name, get_failure_hook_name, get_creation_hook_name
44
from jsonfield import JSONField
55
from model_utils import Choices
6+
import datetime
67
import logging
78
import uuid
89

910

1011
logger = logging.getLogger(__name__)
1112

1213

14+
DELETE_JOBS_AFTER_HOURS = 24
15+
16+
1317
class JobManager(models.Manager):
1418

1519
def get_ready_or_none(self, queue_name, max_retries=3):
@@ -38,6 +42,15 @@ def get_ready_or_none(self, queue_name, max_retries=3):
3842
retries_left -= 1
3943
logger.warn("Caught %s when looking for a READY job, retrying %s more times", str(e), retries_left)
4044

45+
def delete_old(self):
46+
"""
47+
Delete all jobs older than DELETE_JOBS_AFTER_HOURS
48+
"""
49+
delete_jobs_in_states = [Job.STATES.FAILED, Job.STATES.COMPLETE]
50+
delete_jobs_created_before = datetime.datetime.utcnow() - datetime.timedelta(hours=DELETE_JOBS_AFTER_HOURS)
51+
logger.info("Deleting all job in states %s created before %s", ", ".join(delete_jobs_in_states), delete_jobs_created_before.isoformat())
52+
Job.objects.filter(state__in=delete_jobs_in_states, created__lte=delete_jobs_created_before).delete()
53+
4154

4255
class Job(models.Model):
4356

django_dbq/tests.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,30 @@ def test_failure_hook(self):
171171
job = Job.objects.get()
172172
self.assertEqual(job.state, Job.STATES.FAILED)
173173
self.assertEqual(job.workspace['output'], 'failure hook ran')
174+
175+
176+
@override_settings(JOBS={'testjob': {'tasks': ['a']}})
177+
class DeleteOldJobsTestCase(TestCase):
178+
179+
def test_delete_old_jobs(self):
180+
two_days_ago = datetime.utcnow() - timedelta(days=2)
181+
182+
j1 = Job.objects.create(name='testjob', state=Job.STATES.COMPLETE)
183+
j1.created = two_days_ago
184+
j1.save()
185+
186+
j2 = Job.objects.create(name='testjob', state=Job.STATES.FAILED)
187+
j2.created = two_days_ago
188+
j2.save()
189+
190+
j3 = Job.objects.create(name='testjob', state=Job.STATES.NEW)
191+
j3.created = two_days_ago
192+
j3.save()
193+
194+
j4 = Job.objects.create(name='testjob', state=Job.STATES.COMPLETE)
195+
196+
Job.objects.delete_old()
197+
198+
self.assertEqual(Job.objects.count(), 2)
199+
self.assertTrue(j3 in Job.objects.all())
200+
self.assertTrue(j4 in Job.objects.all())

0 commit comments

Comments
 (0)