From e1d27b637caa1399d32f35f45437f0e9791fc086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Kl=C3=BCnder?= Date: Fri, 10 Nov 2017 23:23:22 +0100 Subject: [PATCH] process_updates() don't lock globally, but only on unprocessed updates --- .../mapdata/management/commands/processupdates.py | 6 +++++- src/c3nav/mapdata/models/update.py | 4 ++-- src/c3nav/mapdata/tasks.py | 12 +++++++++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/c3nav/mapdata/management/commands/processupdates.py b/src/c3nav/mapdata/management/commands/processupdates.py index b309c7c6..02bea85e 100644 --- a/src/c3nav/mapdata/management/commands/processupdates.py +++ b/src/c3nav/mapdata/management/commands/processupdates.py @@ -1,5 +1,6 @@ from django.conf import settings from django.core.management.base import BaseCommand +from django.db import DatabaseError from django.utils.translation import ugettext_lazy as _ from c3nav.mapdata.tasks import process_map_updates @@ -9,7 +10,10 @@ class Command(BaseCommand): help = 'process unprocessed map updates' def handle(self, *args, **options): - process_map_updates() + try: + process_map_updates() + except DatabaseError: + print(_('Error: There is already map update processing in progress.')) if not settings.HAS_REAL_CACHE: print(_('You have no external cache configured, so don\'t forget to restart your c3nav instance!')) diff --git a/src/c3nav/mapdata/models/update.py b/src/c3nav/mapdata/models/update.py index fedb4ebc..f6b1e126 100644 --- a/src/c3nav/mapdata/models/update.py +++ b/src/c3nav/mapdata/models/update.py @@ -81,8 +81,8 @@ class MapUpdate(models.Model): @classmethod def process_updates(cls): - with cls.lock(): - new_updates = tuple(cls.objects.filter(processed=False)) + with transaction.atomic(): + new_updates = tuple(cls.objects.filter(processed=False).select_for_update(nowait=True)) if not new_updates: return () diff --git a/src/c3nav/mapdata/tasks.py b/src/c3nav/mapdata/tasks.py index b5c2b03b..606a2849 100644 --- a/src/c3nav/mapdata/tasks.py +++ b/src/c3nav/mapdata/tasks.py @@ -1,3 +1,4 @@ +from django.db import DatabaseError from django.utils.formats import date_format from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ungettext_lazy @@ -5,10 +6,15 @@ from django.utils.translation import ungettext_lazy from c3nav.celery import app -@app.task(rate_limit='1/m') -def process_map_updates(): +@app.task(bind=True, max_retries=10) +def process_map_updates(self): from c3nav.mapdata.models import MapUpdate - updates = MapUpdate.process_updates() + try: + updates = MapUpdate.process_updates() + except DatabaseError: + if self.request.called_directly: + raise + raise self.retry(countdown=30) if updates: print()