mirror of
https://github.com/pretix/pretix.git
synced 2026-05-20 17:44:02 +00:00
Add simple locking mechanism
This commit is contained in:
@@ -28,6 +28,7 @@ from functools import cached_property
|
||||
from itertools import groupby
|
||||
|
||||
import sentry_sdk
|
||||
from django.db import transaction, DatabaseError
|
||||
from django.db.models import F, Window
|
||||
from django.db.models.functions import RowNumber
|
||||
from django.dispatch import receiver
|
||||
@@ -41,6 +42,7 @@ from pretix.base.logentrytype_registry import make_link
|
||||
from pretix.base.models.datasync import OrderSyncQueue, OrderSyncResult
|
||||
from pretix.base.signals import EventPluginRegistry, periodic_task
|
||||
from pretix.celery_app import app
|
||||
from pretix.helpers import OF_SELF
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -56,7 +58,6 @@ sync_targets = EventPluginRegistry({"identifier": lambda o: o.identifier})
|
||||
def sync_event_to_target(event, target_cls, queued_orders):
|
||||
with scope(organizer=event.organizer):
|
||||
with target_cls(event=event) as p:
|
||||
# TODO: should I somehow lock the queued orders or events, to avoid syncing them twice at the same time?
|
||||
p.sync_queued_orders(queued_orders)
|
||||
|
||||
|
||||
@@ -71,11 +72,10 @@ def sync_all():
|
||||
partition_by=[F("event_id")],
|
||||
order_by="not_before",
|
||||
))
|
||||
.select_related("order")
|
||||
.prefetch_related("event")
|
||||
[:1000]
|
||||
)
|
||||
grouped = groupby(sorted(queue, key=lambda q: (q.sync_provider, q.order.event.pk)), lambda q: (q.sync_provider, q.order.event))
|
||||
grouped = groupby(sorted(queue, key=lambda q: (q.sync_provider, q.event.pk)), lambda q: (q.sync_provider, q.event))
|
||||
for (target, event), queued_orders in grouped:
|
||||
target_cls, meta = sync_targets.get(identifier=target, active_in=event)
|
||||
|
||||
@@ -207,7 +207,17 @@ class OutboundSyncProvider:
|
||||
raise NotImplementedError
|
||||
|
||||
def sync_queued_orders(self, queued_orders):
|
||||
for sq in queued_orders:
|
||||
for queue_item in queued_orders:
|
||||
with transaction.atomic():
|
||||
try:
|
||||
sq = (
|
||||
OrderSyncQueue.objects
|
||||
.select_for_update(of=OF_SELF, nowait=True)
|
||||
.select_related("order")
|
||||
.get(pk=queue_item.pk)
|
||||
)
|
||||
except DatabaseError:
|
||||
continue
|
||||
try:
|
||||
mapped_objects = self.sync_order(sq.order)
|
||||
except UnrecoverableSyncError as e:
|
||||
|
||||
Reference in New Issue
Block a user