refactor: move workflow execution writes to uow

This commit is contained in:
jxxghp
2026-08-22 13:21:52 +08:00
parent fa2bf1fe4d
commit e61b5168ad
17 changed files with 389 additions and 52 deletions
+1 -7
View File
@@ -7,7 +7,7 @@ from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.ext.asyncio import AsyncSession
from app.db.base import Base, get_id_column
from app.db.decorators import db_query, db_update, async_db_query, async_db_update
from app.db.decorators import db_query, async_db_query, async_db_update
class Workflow(Base):
@@ -130,7 +130,6 @@ class Workflow(Base):
return result.scalars().first()
@classmethod
@db_update
def update_state(cls, db, wid: int, state: str):
db.execute(update(cls).where(cls.id == wid).values(state=state))
return True
@@ -142,7 +141,6 @@ class Workflow(Base):
return True
@classmethod
@db_update
def start(cls, db, wid: int):
db.execute(update(cls).where(cls.id == wid).values(state='R'))
return True
@@ -154,7 +152,6 @@ class Workflow(Base):
return True
@classmethod
@db_update
def fail(cls, db, wid: int, result: str):
db.execute(update(cls).where(
and_(cls.id == wid, cls.state != "P")
@@ -178,7 +175,6 @@ class Workflow(Base):
return True
@classmethod
@db_update
def success(cls, db, wid: int, result: Optional[str] = None):
db.execute(update(cls).where(
and_(cls.id == wid, cls.state != "P")
@@ -204,7 +200,6 @@ class Workflow(Base):
return True
@classmethod
@db_update
def reset(cls, db, wid: int, reset_count: Optional[bool] = False):
db.execute(update(cls).where(cls.id == wid).values(
state='W',
@@ -230,7 +225,6 @@ class Workflow(Base):
return True
@classmethod
@db_update
def update_current_action(cls, db, wid: int, action_id: str, context: dict,
execution_state: Optional[dict] = None):
workflow = db.execute(select(cls).where(cls.id == wid)).scalars().first()
+103 -2
View File
@@ -1,4 +1,4 @@
from typing import List, Mapping, Tuple, Optional, Any
from typing import List, Mapping, Tuple, Optional, Any, Protocol
from sqlalchemy import delete as sqlalchemy_delete
@@ -6,6 +6,56 @@ from app.db.base import DbOper
from app.db.models.workflow import Workflow
class WorkflowLegacyWriter(Protocol):
"""无显式 Session 的旧 Oper 写入口所需事务服务。"""
def start(self, workflow_id: int) -> bool:
"""提交工作流运行中状态。"""
...
def success(
self,
workflow_id: int,
result: Optional[str] = None,
) -> bool:
"""提交工作流成功状态。"""
...
def fail(self, workflow_id: int, result: str) -> bool:
"""提交工作流失败状态。"""
...
def step(
self,
workflow_id: int,
action_id: str,
context: dict[str, Any],
execution_state: Optional[dict[str, Any]] = None,
) -> bool:
"""提交工作流动作进度。"""
...
def reset(self, workflow_id: int, reset_count: bool = False) -> bool:
"""提交工作流执行状态重置。"""
...
_legacy_writer: Optional[WorkflowLegacyWriter] = None
def configure_workflow_legacy_writer(writer: WorkflowLegacyWriter) -> None:
"""由启动组合根为旧的无 Session Oper 写入口注入事务服务。"""
global _legacy_writer
_legacy_writer = writer
def _get_workflow_legacy_writer() -> WorkflowLegacyWriter:
"""返回已装配的兼容事务服务,避免 Oper 自行创建会话。"""
if _legacy_writer is None:
raise RuntimeError("工作流兼容写服务尚未配置")
return _legacy_writer
class WorkflowOper(DbOper):
"""
工作流管理
@@ -132,24 +182,65 @@ class WorkflowOper(DbOper):
"""
启动
"""
if self._db is None:
return _get_workflow_legacy_writer().start(wid)
return self.stage_start(wid)
def stage_start(self, wid: int) -> bool:
"""在调用方持有的会话中暂存运行中状态。"""
return Workflow.start(self._db, wid)
def success(self, wid: int, result: Optional[str] = None) -> bool:
"""
成功
"""
if self._db is None:
return _get_workflow_legacy_writer().success(wid, result)
return self.stage_success(wid, result)
def stage_success(self, wid: int, result: Optional[str] = None) -> bool:
"""在调用方持有的会话中暂存成功状态。"""
return Workflow.success(self._db, wid, result)
def fail(self, wid: int, result: str) -> bool:
"""
失败
"""
if self._db is None:
return _get_workflow_legacy_writer().fail(wid, result)
return self.stage_fail(wid, result)
def stage_fail(self, wid: int, result: str) -> bool:
"""在调用方持有的会话中暂存失败状态。"""
return Workflow.fail(self._db, wid, result)
def step(self, wid: int, action_id: str, context: dict, execution_state: Optional[dict] = None) -> bool:
def step(
self,
wid: int,
action_id: str,
context: dict[str, Any],
execution_state: Optional[dict[str, Any]] = None,
) -> bool:
"""
步进
"""
if self._db is None:
return _get_workflow_legacy_writer().step(
wid,
action_id,
context,
execution_state,
)
return self.stage_step(wid, action_id, context, execution_state)
def stage_step(
self,
wid: int,
action_id: str,
context: dict[str, Any],
execution_state: Optional[dict[str, Any]] = None,
) -> bool:
"""在调用方持有的会话中暂存动作进度。"""
return Workflow.update_current_action(
self._db,
wid,
@@ -162,4 +253,14 @@ class WorkflowOper(DbOper):
"""
重置
"""
if self._db is None:
return _get_workflow_legacy_writer().reset(wid, reset_count)
return self.stage_execution_reset(wid, reset_count)
def stage_execution_reset(
self,
wid: int,
reset_count: bool = False,
) -> bool:
"""在调用方持有的会话中暂存执行状态重置。"""
return Workflow.reset(self._db, wid, reset_count=reset_count)