Partition workflow execution by tenant
This commit is contained in:
@@ -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,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user