Partition workflow execution by tenant

This commit is contained in:
2026-08-04 09:29:36 +02:00
parent 94cdc82bfd
commit 6e0fcf6b3b
3 changed files with 55 additions and 26 deletions
@@ -779,15 +779,19 @@ def reconcile_pending_instances(
session: Session,
*,
registry: object | None,
tenant_id: str | None = None,
limit: int = 50,
) -> dict[str, object]:
clauses = [
WorkflowInstance.status.in_(("running", "waiting")),
WorkflowInstance.current_step_id.is_not(None),
]
if tenant_id:
clauses.append(WorkflowInstance.tenant_id == tenant_id)
instances = list(
session.scalars(
select(WorkflowInstance)
.where(
WorkflowInstance.status.in_(("running", "waiting")),
WorkflowInstance.current_step_id.is_not(None),
)
.where(*clauses)
.order_by(WorkflowInstance.updated_at, WorkflowInstance.id)
.limit(max(1, min(int(limit), 200)))
.with_for_update(skip_locked=True)
@@ -2875,19 +2879,20 @@ def _notify_handoff(
class SqlWorkflowRuntimeWorker:
def __init__(self, *, registry: object | None = None) -> None:
self._registry = registry
self._standards_reconciled = False
self._standards_reconciled_tenants: set[str | None] = set()
def reconcile_pending(
self,
session: object,
*,
tenant_id: str | None = None,
now: datetime | None = None,
limit: int = 50,
) -> Mapping[str, object]:
if not isinstance(session, Session):
raise TypeError("Workflow reconciliation requires a Session.")
standards: Mapping[str, object] | None = None
if not self._standards_reconciled:
if tenant_id not in self._standards_reconciled_tenants:
from govoplan_workflow_engine.backend.contributions import (
reconcile_workflow_definition_contributions,
)
@@ -2895,11 +2900,14 @@ class SqlWorkflowRuntimeWorker:
standards = reconcile_workflow_definition_contributions(
session,
registry=self._registry,
tenant_ids=((tenant_id,) if tenant_id else ()),
)
self._standards_reconciled = int(standards.get("blocked") or 0) == 0
if int(standards.get("blocked") or 0) == 0:
self._standards_reconciled_tenants.add(tenant_id)
runtime = reconcile_pending_instances(
session,
registry=self._registry,
tenant_id=tenant_id,
limit=limit,
)
from govoplan_workflow_engine.backend.triggers import dispatch_due_work
@@ -2907,6 +2915,7 @@ class SqlWorkflowRuntimeWorker:
triggers = dispatch_due_work(
session,
registry=self._registry,
tenant_id=tenant_id,
now=now,
limit=limit,
)