From 50dbe604c5b1143719381010aaf8ab4bffac9627 Mon Sep 17 00:00:00 2001 From: Neal Clark Date: Wed, 1 Oct 2014 14:46:06 -0700 Subject: [PATCH 1/5] Fixed task_id generation --- periodically/tasks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/periodically/tasks.py b/periodically/tasks.py index b90bab6..5dc8372 100644 --- a/periodically/tasks.py +++ b/periodically/tasks.py @@ -4,7 +4,7 @@ class PeriodicTask(object): @property def task_id(self): - return '%s.%s' % (self.__module__, self.__name__) + return '%s.%s' % (self.__module__, self.__class__.__name__) def run(self): raise RuntimeError('This method must be overridden by your class.') From 55860ab1afc0b4e143f6fad7f16778d632678f72 Mon Sep 17 00:00:00 2001 From: Neal Clark Date: Wed, 1 Oct 2014 14:53:00 -0700 Subject: [PATCH 2/5] Bump version to 0.3.1 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 375a178..6094587 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ def read(fname): setup( name = "django-periodically", - version = "0.3.0", + version = "0.3.1", description='Periodic task management for your Django projects.', url = 'https://github.com/hzdg/django-periodically', long_description=README, From bef17320b73e07f6d0e509f62c3d613da38617d6 Mon Sep 17 00:00:00 2001 From: Neal Clark Date: Thu, 30 Oct 2014 10:51:22 -0700 Subject: [PATCH 3/5] wrap runtasks in an atomic transaction --- periodically/management/commands/runtasks.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/periodically/management/commands/runtasks.py b/periodically/management/commands/runtasks.py index c320f2b..7496856 100644 --- a/periodically/management/commands/runtasks.py +++ b/periodically/management/commands/runtasks.py @@ -1,4 +1,5 @@ from django.core.management.base import BaseCommand, CommandError +from django.db import transaction from ... import register as task_scheduler from optparse import make_option from ...utils import get_scheduler_backends_in_groups @@ -39,17 +40,18 @@ class Command(BaseCommand): ), ) + @transaction.atomic def handle(self, *args, **options): task_ids = args backend_groups = options.get('backend_groups', None) fake = options['fake'] force_execution = options['force_execution'] - + if backend_groups: backends = get_scheduler_backends_in_groups(backend_groups) else: backends = task_scheduler.backends - + for backend in backends: if task_ids: tasks = set([task for task in backend.tasks if task.task_id in task_ids]) From 8e6952e6cc2ea290bff55b23b55a8a6322ab01ee Mon Sep 17 00:00:00 2001 From: Neal Clark Date: Fri, 31 Oct 2014 11:15:15 -0700 Subject: [PATCH 4/5] Add task_id to query to match check_timeout() --- periodically/backends.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/periodically/backends.py b/periodically/backends.py index 61e54e7..35322e6 100644 --- a/periodically/backends.py +++ b/periodically/backends.py @@ -85,7 +85,7 @@ def _run_tasks(self, tasks=None, fake=None, force=False): # If there are still tasks running, don't run the queue (as we # could mess up the order). - if ExecutionRecord.objects.filter(end_time__isnull=True): + if ExecutionRecord.objects.filter(task_id=task.task_id, end_time__isnull=True): print('There are still tasks running; no new tasks will be run') # TODO: Should this behave differently if force == True? return From 733b7b98c3bc8ae79b4a5452329f2317a3b9adbd Mon Sep 17 00:00:00 2001 From: Neal Clark Date: Fri, 31 Oct 2014 11:31:46 -0700 Subject: [PATCH 5/5] Check timeouts on all tasks in this backend --- .gitignore | 1 + periodically/backends.py | 13 ++++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 0205d62..a15a5be 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.pyc +.idea/ .DS_Store diff --git a/periodically/backends.py b/periodically/backends.py index 35322e6..37cd746 100644 --- a/periodically/backends.py +++ b/periodically/backends.py @@ -76,16 +76,19 @@ def _run_tasks(self, tasks=None, fake=None, force=False): registered_task_ids = [task.task_id for task in tasks] + # check the timeouts for every task in the schedule for task, schedule in self._schedules: - if not tasks or task.task_id in registered_task_ids: + # Cancel the task if it's timed out. + # FIXME: This should only be called once per task (no matter how many times it's scheduled). + self.check_timeout(task, now) - # Cancel the task if it's timed out. - # FIXME: This should only be called once per task (no matter how many times it's scheduled). - self.check_timeout(task, now) + for task, schedule in self._schedules: + if not tasks or task.task_id in registered_task_ids: # If there are still tasks running, don't run the queue (as we # could mess up the order). - if ExecutionRecord.objects.filter(task_id=task.task_id, end_time__isnull=True): + # Tasks scheduled with other backends can trigger this check. + if ExecutionRecord.objects.filter(end_time__isnull=True): print('There are still tasks running; no new tasks will be run') # TODO: Should this behave differently if force == True? return