Merge branch 'refactor/remove-redis' into develop
# Conflicts: # .env.example # CLAUDE.md # backend/Dockerfile # backend/pyproject.toml # backend/src/backend/main.py # backend/src/backend/schedule_runs.py # common/src/common/db/models.py # common/src/common/eventing.py # contracts/README.md # contracts/demo-core-v1.md # contracts/events/README.md # contracts/events/event-envelope-v1.json # contracts/locks/README.md # contracts/locks/file-edit-lock-v1.md # contracts/schedules/schedule-definition-api-v1.md # docker-compose.yml # frontend/README.md # migrations/README.md # migrations/versions/20260724_0001_v1_schema_baseline.py # runtime/Dockerfile # runtime/README.md # runtime/pyproject.toml # runtime/src/runtime/main.py # schedule/Dockerfile # schedule/README.md # schedule/pyproject.toml # schedule/src/schedule/main.py # schedule/src/schedule/service.py
This commit is contained in:
@@ -14,14 +14,14 @@ class ConsumerInbox(Base):
|
||||
__tablename__ = 'consumer_inbox'
|
||||
__table_args__ = (
|
||||
Index('idx_consumer_inbox_status', 'consumer_name', 'process_status', 'created_at'),
|
||||
{'comment': '消费者幂等 Inbox,防止 Stream 重投导致重复执行'}
|
||||
{'comment': '消费者幂等 Inbox,防止数据库事件重复处理'}
|
||||
)
|
||||
|
||||
consumer_name: Mapped[str] = mapped_column(String(128), primary_key=True)
|
||||
event_id: Mapped[str] = mapped_column(CHAR(26), primary_key=True)
|
||||
process_status: Mapped[str] = mapped_column(String(16), nullable=False, server_default=text("'processing'"), comment='processing/succeeded/failed')
|
||||
created_at: Mapped[datetime.datetime] = mapped_column(DATETIME(fsp=3), nullable=False, server_default=text('CURRENT_TIMESTAMP(3)'))
|
||||
message_id: Mapped[Optional[str]] = mapped_column(String(128), comment='Redis Stream message ID')
|
||||
message_id: Mapped[Optional[str]] = mapped_column(String(128), comment='数据库事件处理批次标识')
|
||||
processed_at: Mapped[Optional[datetime.datetime]] = mapped_column(DATETIME(fsp=3))
|
||||
error_message: Mapped[Optional[str]] = mapped_column(String(2000))
|
||||
|
||||
@@ -32,7 +32,7 @@ class OutboxEvents(Base):
|
||||
Index('idx_outbox_aggregate', 'aggregate_type', 'aggregate_id', 'created_at'),
|
||||
Index('idx_outbox_idempotency', 'idempotency_key'),
|
||||
Index('idx_outbox_pending', 'event_status', 'available_at', 'created_at'),
|
||||
{'comment': '事务 Outbox;提交后发布到 Redis Streams'}
|
||||
{'comment': '事务 Outbox;由 Schedule Executor 直接轮询处理'}
|
||||
)
|
||||
|
||||
event_id: Mapped[str] = mapped_column(CHAR(26), primary_key=True)
|
||||
@@ -432,14 +432,14 @@ class EditSessions(Base):
|
||||
Index('idx_edit_sessions_object', 'storage_object_id', 'session_status', 'expires_at'),
|
||||
Index('idx_edit_sessions_runtime', 'runtime_id', 'session_status'),
|
||||
Index('idx_edit_sessions_user', 'user_id', 'session_status'),
|
||||
{'comment': '编辑会话审计;实时锁状态以 Redis 为准'}
|
||||
{'comment': '编辑会话与数据库租约;MySQL 为锁状态权威'}
|
||||
)
|
||||
|
||||
edit_session_id: Mapped[str] = mapped_column(CHAR(26), primary_key=True)
|
||||
workspace_id: Mapped[str] = mapped_column(CHAR(26), nullable=False)
|
||||
storage_object_id: Mapped[str] = mapped_column(CHAR(26), nullable=False)
|
||||
user_id: Mapped[str] = mapped_column(CHAR(26), nullable=False)
|
||||
redis_lock_key: Mapped[str] = mapped_column(String(512), nullable=False)
|
||||
lock_key: Mapped[str] = mapped_column(String(512), nullable=False)
|
||||
lock_token_hash: Mapped[bytes] = mapped_column(BINARY(32), nullable=False, comment='不保存原始 token')
|
||||
session_status: Mapped[str] = mapped_column(String(16), nullable=False, server_default=text("'active'"), comment='active/closed/expired/failed')
|
||||
started_at: Mapped[datetime.datetime] = mapped_column(DATETIME(fsp=3), nullable=False, server_default=text('CURRENT_TIMESTAMP(3)'))
|
||||
|
||||
@@ -9,10 +9,10 @@ from common.db.models import OutboxEvents
|
||||
from common.ids import new_ulid
|
||||
|
||||
|
||||
STREAM_BY_EVENT_TYPE = {
|
||||
"schedule.run.requested": "stream:scheduler:commands",
|
||||
"job.node.execute": "stream:jobs:execute",
|
||||
"job.node.finished": "stream:jobs:results",
|
||||
SUPPORTED_EVENT_TYPES = {
|
||||
"schedule.run.requested",
|
||||
"job.node.execute",
|
||||
"job.node.finished",
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ async def add_outbox_event(
|
||||
payload: dict[str, Any],
|
||||
available_at: datetime | None = None,
|
||||
) -> OutboxEvents:
|
||||
if event_type not in STREAM_BY_EVENT_TYPE:
|
||||
if event_type not in SUPPORTED_EVENT_TYPES:
|
||||
raise ValueError(f"unsupported event type: {event_type}")
|
||||
event_id = new_ulid()
|
||||
envelope = {
|
||||
|
||||
Reference in New Issue
Block a user