Optimize refresh_quota_caches for less long-running queries

This commit is contained in:
Raphael Michel
2019-05-27 10:09:29 +02:00
parent e2ce35a85b
commit db63e20708

View File

@@ -1,11 +1,11 @@
from datetime import timedelta from datetime import timedelta
from django.db import models from django.conf import settings
from django.db.models import F, Max, OuterRef, Q, Subquery from django.db.models import Max, Q
from django.dispatch import receiver from django.dispatch import receiver
from django.utils.timezone import now from django.utils.timezone import now
from pretix.base.models import LogEntry, Quota from pretix.base.models import Event, LogEntry
from pretix.celery_app import app from pretix.celery_app import app
from ..signals import periodic_task from ..signals import periodic_task
@@ -18,19 +18,25 @@ def build_all_quota_caches(sender, **kwargs):
@app.task @app.task
def refresh_quota_caches(): def refresh_quota_caches():
last_activity = LogEntry.objects.filter( # Active events
event=OuterRef('event_id'), active = LogEntry.objects.using(settings.DATABASE_REPLICA).filter(
datetime__gt=now() - timedelta(days=7)
).order_by().values('event').annotate( ).order_by().values('event').annotate(
m=Max('datetime') last_activity=Max('datetime')
).values(
'm'
) )
quotas = Quota.objects.annotate( for a in active:
last_activity=Subquery(last_activity, output_field=models.DateTimeField()) try:
).filter( e = Event.objects.using(settings.DATABASE_REPLICA).get(pk=a['event'])
Q(cached_availability_time__isnull=True) | except Event.DoesNotExist:
Q(cached_availability_time__lt=F('last_activity')) | continue
Q(cached_availability_time__lt=now() - timedelta(hours=2), last_activity__gt=now() - timedelta(days=7)) quotas = e.quotas.filter(
).select_related('subevent') Q(cached_availability_time__isnull=True) |
for q in quotas: Q(cached_availability_time__lt=a['last_activity']) |
q.availability() Q(cached_availability_time__lt=now() - timedelta(hours=2))
).filter(
Q(subevent__isnull=True) |
Q(subevent__date_to__isnull=False, subevent__date_to__gte=now() - timedelta(days=14)) |
Q(subevent__date_from__gte=now() - timedelta(days=14))
)
for q in quotas:
q.availability()