项目结构:

python
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/5/27 21:03
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : structured_logger.py
import json
from datetime import datetime
class StructuredLogger:
"""
结构化日志适配器
"""
@staticmethod
def info(msg: str, **kwargs):
"""
:param msg:
:param kwargs:
:return:
"""
timestamp = datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f+0800")[:-3]
log_entry = {"level": "info", "time": timestamp, "msg": msg, **kwargs}
print(json.dumps(log_entry, ensure_ascii=False))
def error(self, msg: str, **kwargs):
timestamp = datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f+0800")[:-3]
log_entry = {"level": "error", "time": timestamp, "msg": msg, **kwargs}
print(json.dumps(log_entry, ensure_ascii=False))
def warning(self, msg: str, **kwargs):
timestamp = datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f+0800")[:-3]
log_entry = {"level": "warning", "time": timestamp, "msg": msg, **kwargs}
print(json.dumps(log_entry, ensure_ascii=False))
def alert(self, msg: str, **kwargs):
timestamp = datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f+0800")[:-3]
log_entry = {"level": "alert", "time": timestamp, "msg": msg, **kwargs}
print(json.dumps(log_entry, ensure_ascii=False))
@staticmethod
def separator():
print("========================================")
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/5/27 20:52
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : registry.py
from typing import Dict, Callable, Optional
from dataclasses import dataclass
import time
@dataclass
class StepDefinition:
"""
步骤元数据定义(支持动态注册)
"""
name: str
duration: float
executor: Callable # 步骤执行函数
stage: str # 所属阶段(生产/入库/发货)
class WorkflowRegistry:
"""
工作流注册中心(单例模式)
"""
_instance = None
_steps: Dict[str, StepDefinition] = {}
_stage_steps: Dict[str, list] = {"production": [], "inventory": [], "shipping": []}
def __new__(cls):
"""
"""
if cls._instance is None:
cls._instance = super(WorkflowRegistry, cls).__new__(cls)
return cls._instance
def register_step(self, step: StepDefinition) -> None:
"""
动态注册新步骤
:param step:
:return:
"""
self._steps[step.name] = step
self._stage_steps[step.stage].append(step)
print(f"[注册中心] 已注册步骤: {step.name} ({step.stage}) | 耗时: {step.duration}s")
def get_stage_steps(self, stage: str) -> list:
"""
获取阶段所有步骤(含动态新增)
:param stage:
:return:
"""
return self._stage_steps.get(stage, [])
def get_step_count(self, stage: str) -> int:
"""
实时计算阶段步骤数量(支持动态扩展)
:param stage:
:return:
"""
return len(self._stage_steps.get(stage, []))
# === DYNAMIC STEP ENHANCEMENT ===
@classmethod
def init_default_steps(cls):
"""
初始化默认步骤(保留原有流程)
:return:
"""
registry = cls()
# 生产阶段
registry.register_step(StepDefinition("款式设计", 3.0, lambda ctx: time.sleep(3.0), "production"))
registry.register_step(StepDefinition("原料采购", 2.0, lambda ctx: time.sleep(2.0), "production"))
registry.register_step(StepDefinition("工艺加工", 4.0, lambda ctx: time.sleep(4.0), "production"))
registry.register_step(StepDefinition("品质质检", 2.0, lambda ctx: time.sleep(2.0), "production"))
registry.register_step(StepDefinition("成品包装", 1.0, lambda ctx: time.sleep(1.0), "production"))
# 入库阶段
registry.register_step(StepDefinition("档案归档", 1.0, lambda ctx: time.sleep(1.0), "inventory"))
registry.register_step(StepDefinition("库存更新", 1.0, lambda ctx: time.sleep(1.0), "inventory"))
registry.register_step(StepDefinition("贴标入仓", 1.0, lambda ctx: time.sleep(1.0), "inventory"))
registry.register_step(StepDefinition("入库核验", 1.0, lambda ctx: time.sleep(1.0), "inventory"))
registry.register_step(StepDefinition("成品拍照", 1.0, lambda ctx: time.sleep(1.0), "inventory"))
# 发货阶段
registry.register_step(StepDefinition("批量发货", 2.0, lambda ctx: time.sleep(2.0), "shipping"))
return registry
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/5/27 20:56
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : settings.py
class WorkflowConfig:
"""工作流全局配置"""
PRODUCTION_STEPS_COUNT = 5
INVENTORY_STEPS_COUNT = 5
SHIPPING_STEPS_COUNT = 1
# 模拟耗时(秒)
STEP_DURATIONS = {
"成品包装": 1.0, "原料采购": 2.0, "款式设计": 3.0,
"工艺加工": 4.0, "品质质检": 2.0, "档案归档": 1.0,
"库存更新": 1.0, "贴标入仓": 1.0, "入库核验": 1.0,
"成品拍照": 1.0, "批量发货": 2.0
}
RETRY_POLICY = {
"strategy": "指数退避",
"max_retries": 2
}
python
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/5/27 20:54
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : dynamic_barrier.py
import threading
import time
from typing import Dict, List, Set
from NBarrierPattern.domain.exceptions import BarrierTimeoutError
class DynamicNBarrier:
"""
支持动态参与者的弹性屏障
"""
def __init__(self, barrier_id: str, timeout: float = 30.0):
self.barrier_id = barrier_id
self.timeout = timeout
self._lock = threading.RLock()
self._condition = threading.Condition(self._lock)
self._participants: Dict[str, bool] = {} # worker_id -> is_arrived
self._completion_time = None
self._reset_flag = False
def register(self, worker_id: str) -> None:
"""
动态注册新参与者(运行时可调用)
:param worker_id:
:return:
"""
with self._lock:
if worker_id not in self._participants:
self._participants[worker_id] = False
print(f"[屏障] {self.barrier_id} 新注册参与者: {worker_id}")
def wait(self, worker_id: str, context: dict) -> dict:
"""
带超时控制的等待(支持动态参与者)
:param worker_id:
:param context:
:return:
"""
start_time = time.time()
with self._condition:
# 标记到达
if worker_id not in self._participants:
raise ValueError(f"参与者 {worker_id} 未注册到屏障 {self.barrier_id}")
self._participants[worker_id] = True
# 检查是否全部到达
while not all(self._participants.values()) and not self._reset_flag:
elapsed = time.time() - start_time
if elapsed > self.timeout:
raise BarrierTimeoutError(
self.barrier_id,
[w for w, arrived in self._participants.items() if not arrived]
)
self._condition.wait(self.timeout - elapsed)
# 记录完成时间
self._completion_time = time.time() - start_time
return {
"barrier_id": self.barrier_id,
"synchronized_workers": len(self._participants),
"active_workers": list(self._participants.keys()),
"completion_time": round(self._completion_time, 4),
**context
}
def reset(self) -> None:
"""
重置屏障状态(供新批次流程使用)
:return:
"""
with self._condition:
self._participants = {w: False for w in self._participants}
self._reset_flag = True
self._condition.notify_all()
self._reset_flag = False
def remove(self, worker_id: str) -> None:
"""
移除参与者(动态取消注册)
:param worker_id:
:return:
"""
with self._condition:
if worker_id in self._participants:
del self._participants[worker_id]
print(f"[屏障] {self.barrier_id} 移除参与者: {worker_id}")
self._condition.notify_all()
def get_status(self) -> dict:
"""
实时获取屏障状态(用于监控)
:return:
"""
with self._lock:
return {
"barrier_id": self.barrier_id,
"total_participants": len(self._participants),
"arrived_count": sum(1 for arrived in self._participants.values() if arrived),
"pending_workers": [w for w, arrived in self._participants.items() if not arrived]
}
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/5/27 21:00
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : n_barrier.py
from threading import Barrier as ThreadBarrier, BrokenBarrierError
import time
from NBarrierPattern.domain.exceptions import BarrierTimeoutError
import threading
import time
from typing import Dict, List, Set
class NBarrier:
"""
企业级N-Barrier实现
"""
def __init__(self, parties: int, barrier_id: str, timeout: float = 30.0):
"""
:param parties:
:param barrier_id:
:param timeout:
"""
self._parties = parties
self._timeout = timeout
self._barrier = ThreadBarrier(parties, timeout=timeout)
self.barrier_id = barrier_id
self.participants: Dict[str, bool] = {}
self._completion_time = None
self._lock = threading.RLock()
def _reset_barrier(self):
"""
重置屏障(当屏障损坏时调用)
:return:
"""
with self._lock:
self._parties = len(self.participants) if self.participants else self._parties
self._barrier = ThreadBarrier(self._parties, timeout=self._timeout)
self.participants = {w: False for w in self.participants}
def register(self, worker_id: str) -> None:
"""
注册参与方
:param worker_id:
:return:
"""
with self._lock:
if worker_id not in self.participants:
self.participants[worker_id] = False
# 动态调整屏障大小
if len(self.participants) > self._parties:
self._parties = len(self.participants)
self._barrier = ThreadBarrier(self._parties, timeout=self._timeout)
def wait(self, worker_id: str, context: dict) -> dict:
"""
带上下文的等待与审计记录生成
:param worker_id:
:param context:
:return:
"""
try:
self.participants[worker_id] = True
start = time.time()
self._barrier.wait()
self._completion_time = time.time() - start
return {
"barrier_id": self.barrier_id,
"synchronized_workers": len(self.participants),
"active_workers": [w for w, s in self.participants.items() if s],
"completion_time": round(self._completion_time, 4),
**context
}
except BrokenBarrierError:
self._reset_barrier()
raise BarrierTimeoutError(
self.barrier_id,
[w for w, s in self.participants.items() if not s]
)
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/5/27 21:54
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : workflow_engine.py
from NBarrierPattern.config.registry import WorkflowRegistry
from NBarrierPattern.core.barrier.dynamic_barrier import DynamicNBarrier
from NBarrierPattern.services.stage_service import StageService
from NBarrierPattern.adapters.logging.structured_logger import StructuredLogger
from NBarrierPattern.domain.models import WorkflowContext
from NBarrierPattern.domain.events import QualityPassedEvent, ArchivingCompletedEvent, EventBus
from NBarrierPattern.services.shipping.service import ShippingServiceWithRetry
class WorkflowOrchestrator(object):
"""
全流程自动化编排引擎
"""
def __init__(self, registry: WorkflowRegistry, logger: StructuredLogger):
"""
:param registry:
:param logger:
"""
self.registry = registry
self.logger = logger
self.context = WorkflowContext()
self.shipping_service = ShippingServiceWithRetry(logger)
# 初始化所有阶段的屏障和服务
self.services = {
"production": self._build_stage_service("production"),
"inventory": self._build_stage_service("inventory"),
"shipping": self._build_stage_service("shipping")
}
# 订阅事件,实现全自动触发
EventBus.subscribe(ArchivingCompletedEvent, self.on_archiving_completed)
def _build_stage_service(self, stage_name: str) -> StageService:
"""
:param stage_name:
:return:
"""
barrier = DynamicNBarrier(f"{stage_name.upper()}_BARRIER")
return StageService(stage_name, self.registry, barrier, self.logger)
def start_production(self):
"""
手动或外部API触发生产流程的起点
:return:
"""
self.logger.info("=== 🏭 阶段1:生产流程启动 ===")
self.services["production"].execute(self.context)
def on_archiving_completed(self, event: ArchivingCompletedEvent):
"""
监听归档完成事件,自动触发后续物理流转
:param event:
:return:
"""
self.logger.separator()
self.logger.info("🔗 接收到归档完成信号,准备跨入物理流转阶段...",
workflow_id=event.workflow_id,
archive_id=event.archive_id)
# 1. 自动触发入库流程
self.logger.info("=== 📦 阶段2:自动触发入库流程 ===")
self.services["inventory"].execute(self.context)
# 2. 自动触发送货流程
self.logger.info("=== 🚚 阶段3:自动触发送货流程 ===")
self.services["shipping"].execute(self.context)
# 3. 输出最终全链路闭环结果
self.logger.separator()
self.logger.info("🎉 珠宝全生命周期管理流程完美闭环!",
workflow_id=self.context.workflow_id,
final_status="已发货",
archive_id=event.archive_id)
# 触发带重试保护的发货流程
self.logger.info("=== 🚚 阶段3:启动智能发货流程 ===")
self.shipping_service.execute_shipping_with_retry(self.context)
# 根据最终状态输出结果
if self.context.shipping_status.name == 'SUCCESS':
self.logger.info("🎉 全链路闭环完成!")
else:
self.logger.alert("⚠️ 流程异常终止,请检查工单系统",
final_state=self.context.shipping_status.value)
python
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/5/27 21:43
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : events.py
from dataclasses import dataclass, field
from typing import List, Callable
import uuid
from datetime import datetime
from threading import Thread
@dataclass
class QualityPassedEvent:
"""
质检通过领域事件
"""
workflow_id: str
product_sku: str
passed_at: str = field(default_factory=lambda: datetime.now().isoformat())
metadata: dict = field(default_factory=dict)
@dataclass
class ArchivingCompletedEvent:
"""
归档完成领域事件(触发发货的开关)
"""
workflow_id: str
archive_id: str
storage_zone: str
archived_at: str = field(default_factory=lambda: datetime.now().isoformat())
class EventBus:
"""
轻量级内存事件总线
"""
_subscribers: dict = {}
@classmethod
def subscribe(cls, event_type: type, handler: Callable):
if event_type not in cls._subscribers:
cls._subscribers[event_type] = []
cls._subscribers[event_type].append(handler)
@classmethod
def publish(cls, event):
event_type = type(event)
if event_type in cls._subscribers:
for handler in cls._subscribers[event_type]:
Thread(target=handler, args=(event,), daemon=True).start()
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/5/27 20:58
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : exceptions.py
class BarrierTimeoutError(Exception):
"""
屏障超时异常
"""
def __init__(self, barrier_id: str, pending_workers: list):
"""
:param barrier_id:
:param pending_workers:
"""
self.barrier_id = barrier_id
self.pending_workers = pending_workers
super().__init__(f"屏障{barrier_id}超时,未到达节点:{pending_workers}")
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/5/27 20:57
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : models.py
from dataclasses import dataclass, field
from typing import Dict, Any
import uuid
from datetime import datetime
from enum import Enum
from NBarrierPattern.domain.QualityStatus import QualityStatus
class ShippingStatus(Enum):
PENDING = "待发货"
DISPATCHING = "下发指令中"
SUCCESS = "已发货"
FAILED_RECOVERABLE = "失败(可重试)" # 如WMS接口超时
FAILED_PERMANENT = "失败(需人工介入)" # 如参数校验不通过
@dataclass
class WorkflowContext:
"""
工作流上下文载体
"""
workflow_id: str = field(default_factory=lambda: f"JW-{datetime.now().strftime('%Y%m%d')}-{uuid.uuid4().hex[:6].upper()}")
quality_status: QualityStatus = QualityStatus.PENDING
shipping_status: ShippingStatus = ShippingStatus.PENDING
rework_count: int = 0 # 记录返工次数,防止死循环
max_rework_attempts: int = 3
metadata: Dict[str, Any] = field(default_factory=dict)
def mark_as_failed(self):
"""
:return:
"""
if self.rework_count >= self.max_rework_attempts:
raise RuntimeError(f"流程{self.workflow_id}返工次数已达上限({self.max_rework_attempts}),强制终止!")
QualityStatus.quality_status = QualityStatus.FAILED
self.rework_count += 1
def mark_as_reworked(self):
"""
:return:
"""
QualityStatus.quality_status = QualityStatus.REWORKED
# 自定义业务异常体系
class BaseShippingException(Exception):
"""
"""
def __init__(self, message: str, is_recoverable: bool):
super().__init__(message)
self.is_recoverable = is_recoverable
class WmsTimeoutError(BaseShippingException):
"""
仓库系统连接超时(可恢复)
"""
def __init__(self):
super().__init__("调用WMS接口超时", True)
class InvalidAddressError(BaseShippingException):
"""
收货地址非法(不可恢复)
"""
def __init__(self, address: str):
super().__init__(f"收货地址无效: {address}", False)
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/5/27 21:29
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : QualityStatus.py
from enum import Enum
class QualityStatus(Enum):
"""质量检验状态"""
PENDING = "待质检"
PASSED = "合格"
FAILED = "不合格(需返工)"
REWORKED = "已返工"
python
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/5/27 21:06
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : BaseStageService.py
from threading import Thread
from NBarrierPattern.config.settings import WorkflowConfig
from NBarrierPattern.core.barrier.n_barrier import NBarrier
from NBarrierPattern.adapters.logging.structured_logger import StructuredLogger
from NBarrierPattern.domain.models import WorkflowContext
import time
class BaseStageService:
"""
阶段基类
"""
def __init__(self, logger: StructuredLogger, barrier: NBarrier, stage_name: str, steps_config: list):
"""
:param logger:
:param barrier:
:param stage_name:
:param steps_config:
"""
self.logger = logger
self.barrier = barrier
self.stage_name = stage_name
self.steps_config = steps_config
def _execute_step(self, step_name: str, duration: float, worker_id: str):
"""
隔离的步骤执行环境
:param step_name:
:param duration:
:param worker_id:
:return:
"""
self.logger.info("开始{}步骤".format(self.stage_name), step=step_name, worker_id=worker_id)
time.sleep(duration)
metrics = {"cost": round(duration + (duration * 0.0001), 7), "retry": 0}
self.logger.info("步骤完成", stage=self.stage_name, step=step_name, worker_id=worker_id, **metrics)
barrier_result = self.barrier.wait(worker_id, metrics)
self.logger.info("=== 【{}屏障通过】 ===".format(self.stage_name), **barrier_result)
def execute(self, context: WorkflowContext):
"""
:param context:
:return:
"""
threads = []
for step_name, duration in self.steps_config.items():
worker_id = f"{self.stage_name.upper()[:4]}-{list(self.steps_config.keys()).index(step_name) + 1}"
self.barrier.register(worker_id)
t = Thread(target=self._execute_step, args=(step_name, duration, worker_id))
threads.append(t)
t.start()
for t in threads:
t.join()
return context
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/5/27 21:22
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : stage_service.py
from threading import Thread
from NBarrierPattern.config.registry import WorkflowRegistry, StepDefinition
from NBarrierPattern.core.barrier.dynamic_barrier import DynamicNBarrier
from NBarrierPattern.adapters.logging.structured_logger import StructuredLogger
from NBarrierPattern.domain.models import WorkflowContext
import time
from typing import Dict, List, Set
class StageService:
"""
支持动态步骤的阶段服务
"""
def __init__(
self,
stage_name: str,
registry: WorkflowRegistry,
barrier: DynamicNBarrier,
logger: StructuredLogger
):
self.stage_name = stage_name
self.registry = registry
self.barrier = barrier
self.logger = logger
self._threads: List[Thread] = []
self._worker_id_counter = 0 # 用于生成唯一worker_id
def add_step(self, step: StepDefinition, context=None) -> None:
"""
运行时动态添加新步骤
:param step:
:param context:
:return:
"""
if step.stage != self.stage_name:
raise ValueError(f"步骤 {step.name} 不属于 {self.stage_name} 阶段")
self.registry.register_step(step)
# === DYNAMIC STEP ENHANCEMENT ===
# 关键:动态注册新参与者到屏障
worker_id = self._generate_worker_id(step.name)
self.barrier.register(worker_id)
try:
step.executor(context) # 执行,传入context
self.barrier.wait(worker_id, {}) # 执行完等待汇合,传入空context
finally:
self.barrier.remove(worker_id) # 离开时移除
self.logger.info("动态添加新步骤",
stage=self.stage_name,
step=step.name,
worker_id=worker_id,
new_barrier_size=self.barrier.get_status()["total_participants"])
def _generate_worker_id(self, step_name: str) -> str:
"""
生成唯一工作ID(阶段缩写+序号)
:param step_name:
:return:
"""
self._worker_id_counter += 1
prefix = self.stage_name[:4].upper()
return f"{prefix}-{self._worker_id_counter}"
def _execute_step(self, step: StepDefinition, worker_id: str, context):
"""
执行步骤(带错误重试)
:param step:
:param worker_id:
:param context:
:return:
"""
start_time = time.time()
try:
self.logger.info("开始步骤", stage=self.stage_name, step=step.name, worker_id=worker_id)
step.executor(context) # 执行实际业务逻辑,传入context
duration = time.time() - start_time
metrics = {
"cost": round(duration, 7),
"retry": 0 # 后续可扩展重试逻辑
}
self.logger.info("步骤完成", stage=self.stage_name, step=step.name, **metrics)
# 通过屏障同步
barrier_result = self.barrier.wait(worker_id, metrics)
self.logger.info("=== 【{}屏障通过】 ===".format(self.stage_name), **barrier_result)
except Exception as e:
self.logger.error("步骤失败", step=step.name, error=str(e))
raise
def execute(self, context: WorkflowContext) -> WorkflowContext:
"""
执行当前阶段所有步骤(含动态新增)
:param context:
:return:
"""
steps = self.registry.get_stage_steps(self.stage_name)
self.logger.info("阶段启动",
stage=self.stage_name,
total_steps=len(steps),
steps=[s.name for s in steps])
# 启动所有步骤线程
for step in steps:
worker_id = self._generate_worker_id(step.name)
# 关键:在线程启动前注册参与者到屏障
self.barrier.register(worker_id)
thread = Thread(
target=self._execute_step,
args=(step, worker_id, context),
name=f"{self.stage_name}-{step.name}"
)
self._threads.append(thread)
thread.start()
# 等待全部完成
for t in self._threads:
t.join()
return context
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/5/27 21:44
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : service.py
import json
import time
import uuid
from NBarrierPattern.adapters.logging.structured_logger import StructuredLogger
from NBarrierPattern.domain.events import QualityPassedEvent, ArchivingCompletedEvent, EventBus
class ArchivingService:
"""
自动化归档服务"
"""
def __init__(self, logger: StructuredLogger):
"""
:param logger:
"""
self.logger = logger
def handle_quality_passed(self, event: QualityPassedEvent):
"""
监听质检通过事件,执行自动归档
:param event:
:return:
"""
self.logger.separator()
self.logger.info("📥 触发自动归档流水线", workflow_id=event.workflow_id, sku=event.product_sku)
# 模拟耗时较长的档案处理操作
time.sleep(0.5)
# 1. 生成唯一的数字资产档案ID
archive_id = f"ARC-{event.workflow_id.split('-')[-1]}-{uuid.uuid4().hex[:8].upper()}"
# 2. 构建标准化档案数据
digital_archive = {
"archive_id": archive_id,
"workflow_id": event.workflow_id,
"product_sku": event.product_sku,
"quality_certified_at": event.passed_at,
"digital_twin_status": "ACTIVE",
"storage_zone": "A-03-GOLD" # 模拟分配仓库货位
}
# 3. 持久化到数据库 / 区块链存证 (此处用日志模拟)
self.logger.info("✅ 数字档案创建成功", **digital_archive)
# === 核心改动:发布归档完成事件,通知下游系统 ===
archiving_done_event = ArchivingCompletedEvent(
workflow_id=event.workflow_id,
archive_id=archive_id,
storage_zone=digital_archive["storage_zone"]
)
EventBus.publish(archiving_done_event)
# 4. 通知下游系统(如ERP或WMS)更新库存状态
self._sync_to_warehouse_system(digital_archive)
return archive_id
def _sync_to_warehouse_system(self, archive_data: dict):
"""
模拟对接外部仓储系统的API
:param archive_data:
:return:
"""
self.logger.info("【API调用】向WMS系统推送入库预占指令",
target="WMS_CORE",
payload=json.dumps(archive_data))
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/5/27 21:05
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : service.py
from threading import Thread
from NBarrierPattern.config.settings import WorkflowConfig
from NBarrierPattern.core.barrier.n_barrier import NBarrier
from NBarrierPattern.adapters.logging.structured_logger import StructuredLogger
from NBarrierPattern.domain.models import WorkflowContext
import time
from NBarrierPattern.services.BaseStageService import BaseStageService
class InventoryService(BaseStageService):
"""
"""
def __init__(self, logger: StructuredLogger, barrier: NBarrier):
"""
:param logger:
:param barrier:
"""
inv_steps = {k: v for k, v in WorkflowConfig.STEP_DURATIONS.items() if k in ["档案归档", "库存更新", "贴标入仓", "入库核验", "成品拍照"]}
super().__init__(logger, barrier, "入库", inv_steps)
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/5/27 21:05
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : service.py
from threading import Thread
from NBarrierPattern.config.settings import WorkflowConfig
from NBarrierPattern.core.barrier.n_barrier import NBarrier
from NBarrierPattern.adapters.logging.structured_logger import StructuredLogger
from NBarrierPattern.domain.models import WorkflowContext, QualityStatus
import time
from NBarrierPattern.services.BaseStageService import BaseStageService
from threading import Thread
from NBarrierPattern.config.registry import WorkflowRegistry
from NBarrierPattern.core.barrier.dynamic_barrier import DynamicNBarrier
class ProductionService(BaseStageService):
"""
"""
def __init__(self, logger: StructuredLogger, barrier: NBarrier):
"""
:param logger:
:param barrier:
"""
super().__init__(logger, barrier, "生产", WorkflowConfig.STEP_DURATIONS)
class ProductionServiceWithRework:
"""
具备自动返工能力的生产阶段服务
"""
def __init__(self, stage_name: str, registry: WorkflowRegistry, barrier: DynamicNBarrier, logger: StructuredLogger):
self.stage_name = stage_name
self.registry = registry
self.barrier = barrier
self.logger = logger
def _execute_single_step(self, step_def, worker_id, context: WorkflowContext):
"""
单步执行器(包含异常冒泡)
:param step_def:
:param worker_id:
:param context:
:return:
"""
try:
self.logger.info("开始步骤", stage=self.stage_name, step=step_def.name, worker_id=worker_id)
step_def.executor(context) # 传入context以便质检步骤修改状态
duration = 1.0 # 模拟耗时
metrics = {"cost": round(duration, 7), "retry": context.rework_count}
self.logger.info("步骤完成", stage=self.stage_name, step=step_def.name, **metrics)
# 只有非质检步骤才需要通过屏障,质检步骤单独处理
if step_def.name != "品质质检":
barrier_result = self.barrier.wait(worker_id, metrics)
self.logger.info("=== 【{}屏障通过】 ===".format(self.stage_name), **barrier_result)
except Exception as e:
self.logger.error("步骤执行异常", step=step_def.name, error=str(e))
raise
def execute_with_rework_loop(self, context: WorkflowContext) -> WorkflowContext:
"""
带自动返工闭环的主执行方法
:param context:
:return:
"""
while True:
steps = self.registry.get_stage_steps(self.stage_name)
threads = []
# 如果是返工批次,需要重置屏障状态,让所有工人重新就位
if context.quality_status == QualityStatus.FAILED:
self.logger.separator()
self.logger.warning("⚠️ 触发自动返工机制",
workflow_id=context.workflow_id,
current_attempt=context.rework_count)
self.barrier.reset() # 关键:重置屏障,准备迎接新一轮同步
# 模拟返工前的物理操作(如退回生产线)
self._trigger_physical_rework_action()
# 启动本轮次的所有线程
for step in steps:
worker_id = f"{self.stage_name[:4].upper()}-{steps.index(step) + 1}"
# 动态注册确保屏障参与者对齐
if worker_id not in self.barrier._participants:
self.barrier.register(worker_id)
t = Thread(target=self._execute_single_step, args=(step, worker_id, context))
threads.append(t)
t.start()
# 等待本轮次全部完成
for t in threads:
t.join()
# === 核心判断:检查质检结果 ===
if context.quality_status == QualityStatus.PASSED or context.quality_status == QualityStatus.REWORKED:
self.logger.info("✅ 质检通过,进入下一阶段", status=context.quality_status.value)
break # 跳出循环,进入入库阶段
elif context.quality_status == QualityStatus.FAILED:
self.logger.warning("❌ 质检未通过,将重新执行生产流程...")
continue # 继续while循环,触发返工
else:
raise RuntimeError("未知的质检状态")
return context
def _trigger_physical_rework_action(self):
"""模拟物理世界的返工操作"""
self.logger.info("【系统指令】下发返工单至车间终端...", action="rework_dispatch")
time.sleep(0.5)
self.logger.info("【系统指令】原料重新上料完成", action="material_reload")
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/5/27 21:05
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : service.py
from threading import Thread
from NBarrierPattern.config.settings import WorkflowConfig
from NBarrierPattern.core.barrier.n_barrier import NBarrier
from NBarrierPattern.adapters.logging.structured_logger import StructuredLogger
from NBarrierPattern.domain.models import WorkflowContext, ShippingStatus, WmsTimeoutError, InvalidAddressError,BaseShippingException
import time
from NBarrierPattern.services.BaseStageService import BaseStageService
import random
class ShippingService(BaseStageService):
"""
"""
def __init__(self, logger: StructuredLogger, barrier: NBarrier):
"""
:param logger:
:param barrier:
"""
self.logger = logger
self.max_retries = 3 # 最大重试次数
self.base_delay = 1.0 # 基础等待时间(秒)
ship_steps = {"批量发货": WorkflowConfig.STEP_DURATIONS["批量发货"]}
super().__init__(logger, barrier, "发货", ship_steps)
class ShippingServiceWithRetry:
"""
"""
def __init__(self, logger: StructuredLogger):
self.logger = logger
self.max_retries = 3 # 最大重试次数
self.base_delay = 1.0 # 基础等待时间(秒)
def _call_wms_api(self, context: WorkflowContext):
"""
模拟调用外部WMS/物流系统API
:param context:
:return:
"""
# 模拟:前两次调用抛出超时异常,第三次成功
if context.metadata.get("wms_attempt", 0) < 2:
context.metadata["wms_attempt"] = context.metadata.get("wms_attempt", 0) + 1
raise WmsTimeoutError()
self.logger.info("【WMS接口】物流单号生成成功", tracking_no="SF123456789")
return {"tracking_no": "SF123456789"}
def execute_shipping_with_retry(self, context: WorkflowContext):
"""
带自动重试机制的发货执行器
:param context:
:return:
"""
attempt = 0
while attempt <= self.max_retries:
try:
attempt += 1
self.logger.info(f"🚚 发起发货请求 (第{attempt}次尝试)", workflow_id=context.workflow_id)
# === 核心业务动作 ===
result = self._call_wms_api(context)
# 成功则更新状态并退出循环
context.metadata.update(result)
ShippingStatus.shipping_status = ShippingStatus.SUCCESS
self.logger.info("✅ 发货流程最终完成", status=ShippingStatus.SUCCESS.value)
return
except BaseShippingException as e:
if not e.is_recoverable:
# 遇到不可恢复异常(如地址错误),直接终止,记录日志等待人工处理
ShippingStatus.shipping_status = ShippingStatus.FAILED_PERMANENT
self.logger.error("❌ 发生不可恢复错误,停止重试", error=str(e))
return
# 遇到可恢复异常,判断是否还有重试机会
if attempt >= self.max_retries:
ShippingStatus.shipping_status = ShippingStatus.FAILED_RECOVERABLE
self.logger.warning("⚠️ 达到最大重试次数,转入死信队列/人工干预",
workflow_id=context.workflow_id)
return
# === 指数退避 + 随机抖动 (Jitter) ===
# 公式:delay = base_delay * (2 ^ (attempt - 1)) + random_jitter
delay = self.base_delay * (2 ** (attempt - 1))
jitter = random.uniform(0, 0.5) # 增加随机性,防止多客户端同步重试导致雪崩
total_wait = delay + jitter
self.logger.warning(f"⏳ 检测到瞬时故障,将在 {total_wait:.2f}s 后重试...",
next_attempt=attempt + 1, reason=str(e))
time.sleep(total_wait)
调用:
python
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3.6 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/5/27 21:13
# User : geovindu
# Product : PyCharm
# Project : pydesginpattern
# File : NBarrierBll.py
from NBarrierPattern.config.registry import WorkflowRegistry,StepDefinition
from NBarrierPattern.config.settings import WorkflowConfig
from NBarrierPattern.core.barrier.n_barrier import NBarrier
from NBarrierPattern.adapters.logging.structured_logger import StructuredLogger
from NBarrierPattern.services.production.service import ProductionService,ProductionServiceWithRework
from NBarrierPattern.services.inventory.service import InventoryService
from NBarrierPattern.services.shipping.service import ShippingService
from NBarrierPattern.domain.models import WorkflowContext, QualityStatus
from NBarrierPattern.services.stage_service import StageService
from threading import Thread
import time
from NBarrierPattern.core.barrier.dynamic_barrier import DynamicNBarrier
import random
from NBarrierPattern.domain.events import EventBus, QualityPassedEvent
from NBarrierPattern.services.archiving.service import ArchivingService
from NBarrierPattern.core.orchestrator.workflow_engine import WorkflowOrchestrator
class NBarrierBll(object):
"""
"""
@staticmethod
def run_basic_flow():
"""
基础流程:无返工/无归档
:return:
"""
logger = StructuredLogger()
logger.title("基础生产流程演示(无返工)")
# 1. 初始化注册表
registry = WorkflowRegistry.init_default_steps()
# 2. 绑定基础质检逻辑
for step in registry.get_steps("production"):
if step.name == "品质质检":
step.executor = NBarrierBll.quality_always_pass
# 3. 启动编排器
orchestrator = WorkflowOrchestrator(registry, logger)
orchestrator.start_production()
@staticmethod
def run_archiving_flow():
"""
归档流程:质检触发归档事件
:return:
"""
logger = StructuredLogger()
logger.title("归档生产流程演示(质检触发归档)")
# 1. 初始化注册表
registry = WorkflowRegistry.init_default_steps()
# 2. 绑定归档版质检
for step in registry.get_steps("production"):
if step.name == "品质质检":
step.executor = NBarrierBll.quality_with_archiving
# 3. 初始化归档服务(自动订阅事件)
ArchivingService(logger)
# 4. 启动编排器
orchestrator = WorkflowOrchestrator(registry, logger)
orchestrator.start_production()
@staticmethod
def run_rework_flow():
"""
返工流程:模拟质检失败重试
:return:
"""
logger = StructuredLogger()
logger.title("返工生产流程演示(30%失败率)")
# 1. 初始化注册表
registry = WorkflowRegistry.init_default_steps()
# 2. 绑定返工版质检
for step in registry.get_steps("production"):
if step.name == "品质质检":
step.executor = NBarrierBll.quality_with_rework
# 3. 初始化返工服务
barrier = DynamicNBarrier("PRODUCTION_BARRIER")
production = ProductionServiceWithRework(
"production",
registry,
barrier,
logger
)
# 4. 执行带返工的生产阶段
context = WorkflowContext()
production.execute_with_rework_loop(context)
# 5. 继续后续流程(入库/发货)
inventory = StageService("inventory", registry, DynamicNBarrier("INVENTORY_BARRIER"), logger)
shipping = StageService("shipping", registry, DynamicNBarrier("SHIPPING_BARRIER"), logger)
inventory.execute(context)
shipping.execute(context)
logger.success("✅ 返工流程完整结束", workflow_id=context.workflow_id)
@staticmethod
def mock_design(context: WorkflowContext):
"""
模拟款式设计
:param context:
:return:
"""
print(f"[{context.workflow_id}] 🎨 款式设计完成")
time.sleep(1)
@staticmethod
def mock_material_procurement(context: WorkflowContext):
"""
模拟原料采购
:param context:
:return:
"""
print(f"[{context.workflow_id}] 💎 原料采购完成")
time.sleep(1)
# --- 质检逻辑变体 ---
@staticmethod
def mock_quality_inspection_always_pass(context: WorkflowContext):
"""
模拟必定通过的质检(用于基础测试)
"""
print("--- 正在进行精密仪器质检 (基础版) ---")
time.sleep(1)
QualityStatus.quality_status = QualityStatus.PASSED
print("判定:合格 ")
@staticmethod
def mock_quality_inspection_with_archiving(context: WorkflowContext):
"""
模拟质检通过并触发归档事件
"""
print("--- 正在进行精密仪器质检 (归档版) ---")
time.sleep(1)
QualityStatus.quality_status = QualityStatus.PASSED
# 发布事件
event = QualityPassedEvent(
workflow_id=context.workflow_id,
product_sku="JW-RING-DIAMOND-001",
metadata={"carat": 1.5, "clarity": "VVS1"}
)
EventBus.publish(event)
print("判定:合格 (已触发归档事件)")
@staticmethod
def mock_quality_inspection_with_rework(context: WorkflowContext):
"""
模拟带返工逻辑的质检(前两次失败,第三次成功)
注意:这里假设 context 是可变的,或者你有办法更新状态
"""
print("--- 正在进行精密仪器质检 (返工版) ---")
time.sleep(1)
# 简单的返工逻辑模拟
if random.random() < 0.3: # 30% 概率失败
print("质检员发现瑕疵!判定:不合格 ")
# 这里应该抛出异常或设置标志位,由外层循环捕获
# 假设 context 有一个属性记录状态
QualityStatus.quality_status = QualityStatus.FAILED
else:
print("复检通过。判定:合格 ")
QualityStatus.quality_status = QualityStatus.PASSED
@staticmethod
def mock_quality_inspection(context):
"""模拟必定通过的质检"""
print("--- 正在进行精密仪器质检 ---")
time.sleep(1.0)
QualityStatus.quality_status = QualityStatus.PASSED
# 发布质检通过事件,交给归档服务处理
from NBarrierPattern.domain.events import QualityPassedEvent
EventBus.publish(QualityPassedEvent(
workflow_id=context.workflow_id,
product_sku="JW-RING-DIAMOND-001",
metadata={"carat": 1.5}
))
# --- 演示用的 demo 方法(建议移至 main.py,但为了方便你测试先留着)---
@staticmethod
def demo_execution(self):
"""
演示执行流程(修复版)
注意:这里只演示一种模式,推荐使用 Orchestrator 模式
"""
from NBarrierPattern.adapters.logging.structured_logger import StructuredLogger
from NBarrierPattern.config.registry import WorkflowRegistry
from NBarrierPattern.core.orchestrator.workflow_engine import WorkflowOrchestrator
logger = StructuredLogger()
logger.info("=== 珠宝全流程生产系统启动 ===")
# 1. 初始化注册中心
registry = WorkflowRegistry.init_default_steps()
# --- 场景1:演示基础流程 ---
logger.info("=== 场景1:基础生产流程(无返工)===")
# 绑定基础质检逻辑
for step in registry.get_steps("production"):
if step.name == "品质质检":
step.executor = self.mock_quality_inspection_always_pass
# 初始化编排器并启动
orchestrator = WorkflowOrchestrator(registry, logger)
# 注意:start_production 可能是异步的,如果需要阻塞等待,看你的 Orchestrator 实现
orchestrator.start_production()
# 简单等待,实际应使用事件或 Future 等待完成
time.sleep(10)
# --- 场景2:演示返工流程 ---
# 注意:这里需要重新初始化 registry 或重置步骤,否则质检逻辑还是上面的那个
logger.info("=== 场景2:带返工的生产流程 ===")
registry2 = WorkflowRegistry.init_default_steps()
for step in registry2.get_steps("production"):
if step.name == "品质质检":
step.executor = self.mock_quality_inspection_with_rework
# 假设你有一个专门处理返工的服务
from NBarrierPattern.services.production.service import ProductionServiceWithRework
from NBarrierPattern.core.barrier.dynamic_barrier import DynamicNBarrier
barrier = DynamicNBarrier("PROD_REWORK")
service = ProductionServiceWithRework("production", registry2, barrier, logger)
context = WorkflowContext()
# 执行带返工的流程
service.execute_with_rework_loop(context)
logger.info("所有演示场景完成")
def demo(self):
"""
:return:
"""
logger = StructuredLogger()
logger.info("=== 珠宝全流程生产系统启动 ===")
logger.info("配置加载完成",
生产步骤=WorkflowConfig.PRODUCTION_STEPS_COUNT,
入库步骤=WorkflowConfig.INVENTORY_STEPS_COUNT,
重试策略=WorkflowConfig.RETRY_POLICY["strategy"])
context = WorkflowContext()
registry = WorkflowRegistry.init_default_steps() # 初始化默认步骤
# 绑定自定义质检逻辑
for step in registry._stage_steps["production"]:
if step.name == "品质质检":
step.executor = NBarrierBll.mock_quality_inspection
# 初始化归档服务(内部会自动订阅质检通过事件)
ArchivingService(logger)
# 初始化编排引擎(内部会自动订阅归档完成事件)
orchestrator = WorkflowOrchestrator(registry, logger)
logger.info("=== 💎 珠宝全流程智能生产系统就绪 ===")
# 仅需一行代码触发生产,后续所有环节全自动流转
orchestrator.start_production()
# 初始化归档服务并注册事件监听器
archiving_service = ArchivingService(logger)
EventBus.subscribe(QualityPassedEvent, archiving_service.handle_quality_passed)
# 替换原有的品质质检执行器
for step in registry._stage_steps["production"]:
if step.name == "品质质检":
step.executor = NBarrierBll.mock_quality_inspection_with_archiving
prod_barrier = DynamicNBarrier("PRODUCTION_BARRIER")
production = StageService("production", registry, prod_barrier, logger)
context = WorkflowContext()
logger.info("=== 珠宝全流程生产系统启动(含自动归档机制)===")
# 执行生产阶段(包含质检和触发的自动归档)
production.execute(context)
logger.separator()
logger.info("🎉 质检归档完成,准备进入物理入库环节...", workflow_id=context.workflow_id)
# 替换原有的品质质检执行器为我们自定义的模拟函数
for step in registry._stage_steps["production"]:
if step.name == "品质质检":
step.executor = NBarrierBll.mock_quality_inspection
prod_barrier = DynamicNBarrier("PRODUCTION_BARRIER")
production = ProductionServiceWithRework("production", registry, prod_barrier, logger)
# 创建屏障(数量由注册中心动态决定)
prod_barrier = DynamicNBarrier("PRODUCTION_BARRIER")
inv_barrier = DynamicNBarrier("INVENTORY_BARRIER")
ship_barrier = DynamicNBarrier("SHIPPING_BARRIER")
# 创建阶段服务
production = StageService("production", registry, prod_barrier, logger)
inventory = StageService("inventory", registry, inv_barrier, logger)
shipping = StageService("shipping", registry, ship_barrier, logger)
context = WorkflowContext()
# === 动态步骤演示:在生产阶段运行中插入VIP定制 ===
def vip_engraving_task(context=None):
logger.info("【VIP专属】开始激光刻字", duration=1.5)
time.sleep(1.5)
logger.info("【VIP专属】刻字完成", content="永恒之约")
# 模拟生产阶段执行到一半时动态添加步骤
def simulate_dynamic_addition():
time.sleep(4.0) # 等待部分步骤完成
logger.separator()
logger.info("⚠️ 检测到VIP订单,动态插入定制步骤...")
# 创建新步骤定义
vip_step = StepDefinition(
name="VIP定制刻字",
duration=1.5,
executor=vip_engraving_task,
stage="production" # 关键:必须指定所属阶段
)
production.add_step(vip_step) # 动态注册到生产阶段
# 启动动态添加线程(模拟运行时事件)
dynamic_thread = Thread(target=simulate_dynamic_addition, daemon=True)
dynamic_thread.start()
# 执行全流程
logger.info("=== 珠宝全流程生产系统启动 ===")
logger.info("当前配置",
production_steps=registry.get_step_count("production"),
inventory_steps=registry.get_step_count("inventory"))
logger.info("=== 阶段1:生产流程 ===")
production.execute(context)
logger.info("=== 阶段2:入库流程 ===")
inventory.execute(context)
logger.info("=== 阶段3:发货流程 ===")
shipping.execute(context)
# 输出最终屏障状态
logger.separator()
logger.info("✅ 全流程完成",
workflow_id=context.workflow_id,
production_workers=prod_barrier.get_status()["total_participants"],
inventory_workers=inv_barrier.get_status()["total_participants"])
# 1. 初始化屏障与服务
prod_barrier = NBarrier(WorkflowConfig.PRODUCTION_STEPS_COUNT, "PRODUCTION_BARRIER")
prod_service = ProductionService(logger, prod_barrier)
inv_barrier = NBarrier(WorkflowConfig.INVENTORY_STEPS_COUNT, "INVENTORY_BARRIER")
inv_service = InventoryService(logger, inv_barrier)
ship_barrier = NBarrier(WorkflowConfig.SHIPPING_STEPS_COUNT, "SHIPPING_BARRIER")
ship_service = ShippingService(logger, ship_barrier)
# 2. 顺序执行全流程(屏障保证内部并发安全)
logger.info("=== 等待所有生产步骤完成 ===")
prod_service.execute(context)
logger.info("=== 等待所有入库步骤完成 ===")
inv_service.execute(context)
logger.info("=== 等待发货完成 ===")
ship_service.execute(context)
# 3. 汇总结果
total_steps = WorkflowConfig.PRODUCTION_STEPS_COUNT + WorkflowConfig.INVENTORY_STEPS_COUNT + WorkflowConfig.SHIPPING_STEPS_COUNT
logger.separator()
logger.info("✅ 全流程完成", 总任务数=total_steps, 成功数=total_steps, 流程ID=context.workflow_id)
logger.info("✅ 珠宝成品 → 生产 → 入库 → 发货 全流程完成")
logger.separator()
输出:
