Partition durable events by tenant entitlement

This commit is contained in:
2026-08-04 09:29:35 +02:00
parent 451361cc05
commit c1e6c15866
3 changed files with 122 additions and 8 deletions
+44 -7
View File
@@ -61,15 +61,21 @@ class SqlAuditOutbox:
self,
session: object,
*,
tenant_id: str | None = None,
tenantless_only: bool = False,
consumers: Sequence[DurableEventConsumer] = (),
observer: EventDispatcher | None = publish_platform_event,
dispatcher: EventDispatcher | None = None,
limit: int = 100,
) -> dict[str, int]:
if tenant_id is not None and tenantless_only:
raise ValueError(
"Tenant and tenantless event filters are mutually exclusive"
)
db = _session(session)
now = datetime.now(timezone.utc)
consumers_by_id = _consumer_map(consumers)
rows = (
query = (
db.query(AuditOutboxEvent)
.filter(
AuditOutboxEvent.status.in_(
@@ -77,7 +83,20 @@ class SqlAuditOutbox:
),
or_(AuditOutboxEvent.next_attempt_at.is_(None), AuditOutboxEvent.next_attempt_at <= now),
)
.order_by(AuditOutboxEvent.created_at.asc(), AuditOutboxEvent.id.asc())
)
if tenant_id:
query = query.filter(
AuditOutboxEvent.payload["tenant"]["id"].as_string()
== tenant_id
)
elif tenantless_only:
query = query.filter(
AuditOutboxEvent.payload["tenant"]["id"]
.as_string()
.is_(None)
)
rows = (
query.order_by(AuditOutboxEvent.created_at.asc(), AuditOutboxEvent.id.asc())
.with_for_update(skip_locked=True)
.limit(max(1, min(int(limit), 500)))
.all()
@@ -179,18 +198,36 @@ class SqlAuditOutbox:
self,
session: object,
*,
tenant_id: str | None = None,
tenantless_only: bool = False,
before: datetime,
limit: int = 500,
) -> dict[str, int]:
if tenant_id is not None and tenantless_only:
raise ValueError(
"Tenant and tenantless event filters are mutually exclusive"
)
db = _session(session)
clauses = [
AuditOutboxEvent.status == "dispatched",
AuditOutboxEvent.dispatched_at.is_not(None),
AuditOutboxEvent.dispatched_at < before,
]
if tenant_id:
clauses.append(
AuditOutboxEvent.payload["tenant"]["id"].as_string()
== tenant_id
)
elif tenantless_only:
clauses.append(
AuditOutboxEvent.payload["tenant"]["id"]
.as_string()
.is_(None)
)
ids = tuple(
db.scalars(
select(AuditOutboxEvent.id)
.where(
AuditOutboxEvent.status == "dispatched",
AuditOutboxEvent.dispatched_at.is_not(None),
AuditOutboxEvent.dispatched_at < before,
)
.where(*clauses)
.order_by(
AuditOutboxEvent.dispatched_at,
AuditOutboxEvent.id,