mirror of
https://github.com/pretix/pretix.git
synced 2026-05-16 17:03:58 +00:00
Store need_manual_retry flag for failed sync attempts
This commit is contained in:
@@ -66,7 +66,7 @@ def sync_all():
|
|||||||
with scopes_disabled():
|
with scopes_disabled():
|
||||||
queue = (
|
queue = (
|
||||||
OrderSyncQueue.objects
|
OrderSyncQueue.objects
|
||||||
.filter(not_before__lt=now())
|
.filter(not_before__lt=now(), need_manual_retry__isnull=True)
|
||||||
.order_by(Window(
|
.order_by(Window(
|
||||||
expression=RowNumber(),
|
expression=RowNumber(),
|
||||||
partition_by=[F("event_id")],
|
partition_by=[F("event_id")],
|
||||||
@@ -231,7 +231,8 @@ class OutboundSyncProvider:
|
|||||||
"error": e.messages,
|
"error": e.messages,
|
||||||
"full_message": e.full_message,
|
"full_message": e.full_message,
|
||||||
})
|
})
|
||||||
sq.delete()
|
sq.need_manual_retry = "unrecoverable"
|
||||||
|
sq.save()
|
||||||
except RecoverableSyncError as e:
|
except RecoverableSyncError as e:
|
||||||
sq.failed_attempts += 1
|
sq.failed_attempts += 1
|
||||||
sq.not_before = self.next_retry_date(sq)
|
sq.not_before = self.next_retry_date(sq)
|
||||||
@@ -246,7 +247,8 @@ class OutboundSyncProvider:
|
|||||||
"error": e.messages,
|
"error": e.messages,
|
||||||
"full_message": e.full_message,
|
"full_message": e.full_message,
|
||||||
})
|
})
|
||||||
sq.delete()
|
sq.need_manual_retry = "recoverable"
|
||||||
|
sq.save()
|
||||||
else:
|
else:
|
||||||
sq.save()
|
sq.save()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -259,7 +261,8 @@ class OutboundSyncProvider:
|
|||||||
"error": [],
|
"error": [],
|
||||||
"full_message": str(e),
|
"full_message": str(e),
|
||||||
})
|
})
|
||||||
sq.delete()
|
sq.need_manual_retry = "unhandled"
|
||||||
|
sq.save()
|
||||||
else:
|
else:
|
||||||
if not all(res.get("action", "") == "nothing_to_do" for res in mapped_objects.values()):
|
if not all(res.get("action", "") == "nothing_to_do" for res in mapped_objects.values()):
|
||||||
sq.order.log_action("pretix.event.order.data_sync.success", {
|
sq.order.log_action("pretix.event.order.data_sync.success", {
|
||||||
|
|||||||
@@ -1,96 +0,0 @@
|
|||||||
# Generated by Django 4.2.16 on 2025-05-07 13:01
|
|
||||||
|
|
||||||
import django.db.models.deletion
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("pretixbase", "0281_event_is_remote"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name="OrderSyncResult",
|
|
||||||
fields=[
|
|
||||||
(
|
|
||||||
"id",
|
|
||||||
models.BigAutoField(
|
|
||||||
auto_created=True, primary_key=True, serialize=False
|
|
||||||
),
|
|
||||||
),
|
|
||||||
("sync_provider", models.CharField(max_length=128)),
|
|
||||||
("external_object_type", models.CharField(max_length=128)),
|
|
||||||
("external_id_field", models.CharField(max_length=128)),
|
|
||||||
("id_value", models.CharField(max_length=128)),
|
|
||||||
("external_link_href", models.CharField(max_length=255, null=True)),
|
|
||||||
(
|
|
||||||
"external_link_display_name",
|
|
||||||
models.CharField(max_length=255, null=True),
|
|
||||||
),
|
|
||||||
("transmitted", models.DateTimeField(auto_now_add=True)),
|
|
||||||
(
|
|
||||||
"order",
|
|
||||||
models.ForeignKey(
|
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
|
||||||
related_name="sync_results",
|
|
||||||
to="pretixbase.order",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"order_position",
|
|
||||||
models.ForeignKey(
|
|
||||||
null=True,
|
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
|
||||||
related_name="sync_results",
|
|
||||||
to="pretixbase.orderposition",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
"indexes": [
|
|
||||||
models.Index(
|
|
||||||
fields=["order", "sync_provider"],
|
|
||||||
name="pretixbase__order_i_3e3c84_idx",
|
|
||||||
)
|
|
||||||
],
|
|
||||||
},
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name="OrderSyncQueue",
|
|
||||||
fields=[
|
|
||||||
(
|
|
||||||
"id",
|
|
||||||
models.BigAutoField(
|
|
||||||
auto_created=True, primary_key=True, serialize=False
|
|
||||||
),
|
|
||||||
),
|
|
||||||
("sync_provider", models.CharField(max_length=128)),
|
|
||||||
("triggered_by", models.CharField(max_length=128)),
|
|
||||||
("triggered", models.DateTimeField(auto_now_add=True)),
|
|
||||||
("failed_attempts", models.PositiveIntegerField(default=0)),
|
|
||||||
("not_before", models.DateTimeField(db_index=True)),
|
|
||||||
(
|
|
||||||
"event",
|
|
||||||
models.ForeignKey(
|
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
|
||||||
related_name="queued_sync_jobs",
|
|
||||||
to="pretixbase.event",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"order",
|
|
||||||
models.ForeignKey(
|
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
|
||||||
related_name="queued_sync_jobs",
|
|
||||||
to="pretixbase.order",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
"ordering": ("triggered",),
|
|
||||||
"unique_together": {("order", "sync_provider")},
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
# Generated by Django 4.2.21 on 2025-06-26 16:59
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('pretixbase', '0281_event_is_remote'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='OrderSyncResult',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
|
||||||
|
('sync_provider', models.CharField(max_length=128)),
|
||||||
|
('external_object_type', models.CharField(max_length=128)),
|
||||||
|
('external_id_field', models.CharField(max_length=128)),
|
||||||
|
('id_value', models.CharField(max_length=128)),
|
||||||
|
('external_link_href', models.CharField(max_length=255, null=True)),
|
||||||
|
('external_link_display_name', models.CharField(max_length=255, null=True)),
|
||||||
|
('transmitted', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sync_results', to='pretixbase.order')),
|
||||||
|
('order_position', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='sync_results', to='pretixbase.orderposition')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'indexes': [models.Index(fields=['order', 'sync_provider'], name='pretixbase__order_i_3e3c84_idx')],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='OrderSyncQueue',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
|
||||||
|
('sync_provider', models.CharField(max_length=128)),
|
||||||
|
('triggered_by', models.CharField(max_length=128)),
|
||||||
|
('triggered', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('failed_attempts', models.PositiveIntegerField(default=0)),
|
||||||
|
('not_before', models.DateTimeField(db_index=True)),
|
||||||
|
('need_manual_retry', models.CharField(null=True)),
|
||||||
|
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='queued_sync_jobs', to='pretixbase.event')),
|
||||||
|
('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='queued_sync_jobs', to='pretixbase.order')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'ordering': ('triggered',),
|
||||||
|
'unique_together': {('order', 'sync_provider')},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -24,6 +24,9 @@ import logging
|
|||||||
from functools import cached_property
|
from functools import cached_property
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.utils.translation import (
|
||||||
|
gettext as _, gettext_lazy, ngettext_lazy, pgettext_lazy,
|
||||||
|
)
|
||||||
|
|
||||||
from pretix.base.models import Event, Order, OrderPosition
|
from pretix.base.models import Event, Order, OrderPosition
|
||||||
|
|
||||||
@@ -48,6 +51,11 @@ class OrderSyncQueue(models.Model):
|
|||||||
triggered = models.DateTimeField(blank=False, null=False, auto_now_add=True)
|
triggered = models.DateTimeField(blank=False, null=False, auto_now_add=True)
|
||||||
failed_attempts = models.PositiveIntegerField(default=0)
|
failed_attempts = models.PositiveIntegerField(default=0)
|
||||||
not_before = models.DateTimeField(blank=False, null=False, db_index=True)
|
not_before = models.DateTimeField(blank=False, null=False, db_index=True)
|
||||||
|
need_manual_retry = models.CharField(blank=True, null=True, choices=[
|
||||||
|
('recoverable', _('Temporary error, retry exceeded')),
|
||||||
|
('unrecoverable', _('Misconfiguration')),
|
||||||
|
('unhandled', _('Unhandled exception'))
|
||||||
|
])
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = (("order", "sync_provider"),)
|
unique_together = (("order", "sync_provider"),)
|
||||||
|
|||||||
Reference in New Issue
Block a user