forked from CGM_Public/pretix_original
Improve performance of send_expire_warnings and expire_orders
This commit is contained in:
@@ -7,6 +7,7 @@ from typing import List, Optional
|
|||||||
|
|
||||||
from celery.exceptions import MaxRetriesExceededError
|
from celery.exceptions import MaxRetriesExceededError
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.core.cache import cache
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.db.models import Exists, F, Max, OuterRef, Q, Sum
|
from django.db.models import Exists, F, Max, OuterRef, Q, Sum
|
||||||
from django.db.models.functions import Greatest
|
from django.db.models.functions import Greatest
|
||||||
@@ -857,14 +858,14 @@ def _perform_order(event: Event, payment_provider: str, position_ids: List[str],
|
|||||||
@receiver(signal=periodic_task)
|
@receiver(signal=periodic_task)
|
||||||
@scopes_disabled()
|
@scopes_disabled()
|
||||||
def expire_orders(sender, **kwargs):
|
def expire_orders(sender, **kwargs):
|
||||||
eventcache = {}
|
event_id = None
|
||||||
|
expire = None
|
||||||
|
|
||||||
for o in Order.objects.filter(expires__lt=now(), status=Order.STATUS_PENDING,
|
for o in Order.objects.filter(expires__lt=now(), status=Order.STATUS_PENDING,
|
||||||
require_approval=False).select_related('event'):
|
require_approval=False).select_related('event').order_by('event_id'):
|
||||||
expire = eventcache.get(o.event.pk, None)
|
if o.event_id != event_id:
|
||||||
if expire is None:
|
expire = settings.get('payment_term_expire_automatically', as_type=bool)
|
||||||
expire = o.event.settings.get('payment_term_expire_automatically', as_type=bool)
|
event_id = o.event_id
|
||||||
eventcache[o.event.pk] = expire
|
|
||||||
if expire:
|
if expire:
|
||||||
mark_order_expired(o)
|
mark_order_expired(o)
|
||||||
|
|
||||||
@@ -872,31 +873,34 @@ def expire_orders(sender, **kwargs):
|
|||||||
@receiver(signal=periodic_task)
|
@receiver(signal=periodic_task)
|
||||||
@scopes_disabled()
|
@scopes_disabled()
|
||||||
def send_expiry_warnings(sender, **kwargs):
|
def send_expiry_warnings(sender, **kwargs):
|
||||||
eventcache = {}
|
|
||||||
today = now().replace(hour=0, minute=0, second=0)
|
today = now().replace(hour=0, minute=0, second=0)
|
||||||
|
days = None
|
||||||
|
event_id = None
|
||||||
|
|
||||||
for o in Order.objects.filter(
|
for o in Order.objects.filter(
|
||||||
expires__gte=today, expiry_reminder_sent=False, status=Order.STATUS_PENDING,
|
expires__gte=today, expiry_reminder_sent=False, status=Order.STATUS_PENDING,
|
||||||
datetime__lte=now() - timedelta(hours=2), require_approval=False
|
datetime__lte=now() - timedelta(hours=2), require_approval=False
|
||||||
).only('pk'):
|
).only('pk', 'event_id').order_by('event_id'):
|
||||||
with transaction.atomic():
|
if event_id != o.event_id:
|
||||||
o = Order.objects.select_related('event').select_for_update().get(pk=o.pk)
|
settings = o.event.settings
|
||||||
if o.status != Order.STATUS_PENDING or o.expiry_reminder_sent:
|
days = cache.get_or_set('{}:{}:setting_mail_days_order_expire_warning'.format('event', o.event_id),
|
||||||
# Race condition
|
default=lambda: settings.get('mail_days_order_expire_warning', as_type=int),
|
||||||
continue
|
timeout=3600)
|
||||||
eventsettings = eventcache.get(o.event.pk, None)
|
event_id = o.event_id
|
||||||
if eventsettings is None:
|
|
||||||
eventsettings = o.event.settings
|
if days and (o.expires - today).days <= days:
|
||||||
eventcache[o.event.pk] = eventsettings
|
with transaction.atomic():
|
||||||
|
o = Order.objects.select_related('event').select_for_update().get(pk=o.pk)
|
||||||
|
if o.status != Order.STATUS_PENDING or o.expiry_reminder_sent:
|
||||||
|
# Race condition
|
||||||
|
continue
|
||||||
|
|
||||||
days = eventsettings.get('mail_days_order_expire_warning', as_type=int)
|
|
||||||
if days and (o.expires - today).days <= days:
|
|
||||||
with language(o.locale):
|
with language(o.locale):
|
||||||
o.expiry_reminder_sent = True
|
o.expiry_reminder_sent = True
|
||||||
o.save(update_fields=['expiry_reminder_sent'])
|
o.save(update_fields=['expiry_reminder_sent'])
|
||||||
email_template = eventsettings.mail_text_order_expire_warning
|
email_template = settings.mail_text_order_expire_warning
|
||||||
email_context = get_email_context(event=o.event, order=o)
|
email_context = get_email_context(event=o.event, order=o)
|
||||||
if eventsettings.payment_term_expire_automatically:
|
if settings.payment_term_expire_automatically:
|
||||||
email_subject = _('Your order is about to expire: %(code)s') % {'code': o.code}
|
email_subject = _('Your order is about to expire: %(code)s') % {'code': o.code}
|
||||||
else:
|
else:
|
||||||
email_subject = _('Your order is pending payment: %(code)s') % {'code': o.code}
|
email_subject = _('Your order is pending payment: %(code)s') % {'code': o.code}
|
||||||
|
|||||||
Reference in New Issue
Block a user