rust: Condition Variable Pattern

本文深入探讨Rust中条件变量模式的实现原理与应用,涵盖std::sync::Condvar的使用方法、与Mutex的协同机制、线程等待与唤醒逻辑,以及在多线程同步场景下的典型设计范式。重点分析其作为同步型设计模式在后端并发编程中的关键作用,避免虚假唤醒并确保线程安全。

项目结构:

//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : coordinator.rs
//! 阶段协调器接口(Phase Coordinator Trait)
//!
//! 条件变量模式的核心抽象:封装「等待条件」与「标记完成并通知」两类原语。
//! - `wait_until_ready`:工位在条件变量上等待「本阶段可开工」的条件;
//! - `mark_complete`:工位完成后推进共享进度并唤醒等待线程。
//!
//! 具体实现由应用层 `ConditionVariableLine` 提供(基于 `Mutex + Condvar`)。

use std::sync::Arc;

use crate::common::logging::Logger;

/// 阶段协调器抽象(线程安全、可共享)
pub trait PhaseCoordinator: Send + Sync {
    /// 获取流水线总阶段数
    ///
    /// # 返回
    /// 总阶段数
    fn total_phases(&self) -> usize;

    /// 获取当前进度(已完成阶段数)
    ///
    /// # 返回
    /// 当前已完成阶段数
    fn current_phase(&self) -> usize;

    /// 等待指定阶段可开工(条件不满足则挂起等待,被唤醒后自动重新检查条件)
    ///
    /// # 参数
    /// - `phase`:阶段序号(从 0 起)
    fn wait_until_ready(&self, phase: usize);

    /// 标记当前工位已完成,推进共享进度并通知所有等待线程
    fn mark_complete(&self);

    /// 获取统一日志对象(对应 ILogger<T>,由 DI 注入)
    ///
    /// # 返回
    /// 统一日志(`Arc<dyn Logger>`)
    fn logger(&self) -> Arc<dyn Logger>;
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : state.rs
//! 生产进度状态(Production State)
//!
//! 条件变量模式中被共享的「共享状态」:记录生产流水线当前已完成到第几个阶段。
//! 该状态受 `Mutex` 保护,配合 `Condvar` 实现多线程等待/通知(条件变量同步)。

/// 生产进度状态(多线程共享、受互斥锁保护)
#[derive(Debug, Clone)]
pub struct ProductionState {
    /// 当前已完成到第几个阶段(0 表示尚未完成任何阶段;推进到 N 表示前 N 个阶段完成)
    pub current_phase: usize,
    /// 当前加工珠宝名称(用于日志与追溯)
    pub jewelry_name: String,
}

impl ProductionState {
    /// 创建生产进度状态
    ///
    /// # 参数
    /// - `jewelry_name`:当前加工珠宝名称
    ///
    /// # 返回
    /// 生产进度状态实例
    pub fn new(jewelry_name: &str) -> Self {
        Self {
            current_phase: 0,
            jewelry_name: jewelry_name.to_string(),
        }
    }

    /// 判断指定阶段是否已就绪(条件判断:当前进度已覆盖该阶段)
    ///
    /// # 参数
    /// - `phase`:阶段序号(从 0 起)
    ///
    /// # 返回
    /// `true` 表示该阶段上游已就绪,可开工;`false` 表示仍需等待
    pub fn is_phase_ready(&self, phase: usize) -> bool {
        self.current_phase >= phase
    }

    /// 推进一个阶段(当前进度 +1,表示一个工位已完成)
    pub fn advance(&mut self) {
        self.current_phase += 1;
    }

    /// 获取当前进度
    ///
    /// # 返回
    /// 当前已完成阶段数
    pub fn phase(&self) -> usize {
        self.current_phase
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : worker.rs
//! 工位接口(Stage Worker Trait)
//!
//! 条件变量模式中的「工位」:代表生产流水线上的一个业务部门。
//! 每个工位在协调器(条件变量)上等待「本阶段可开工」,执行本阶段业务后
//! 标记完成并通知下游,从而形成严格的上下游同步。
//!
//! `perform` 提供默认实现:等待条件 → 执行业务 → 标记完成(条件变量协调流程)。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::condition::coordinator::PhaseCoordinator;
use crate::domain::dtos::process_dtos::{ProcessRequestDto, ProcessResponseDto};

/// 工位抽象(线程安全、可共享)
pub trait StageWorker: Send + Sync {
    /// 获取工位阶段序号(从 0 起,对应供应链顺序)
    ///
    /// # 返回
    /// 阶段序号
    fn stage_index(&self) -> usize;

    /// 获取工位标识(如 PROCUREMENT / DESIGN)
    ///
    /// # 返回
    /// 工位标识
    fn stage_id(&self) -> &str;

    /// 获取工位名称(如 采购部)
    ///
    /// # 返回
    /// 工位名称
    fn stage_name(&self) -> &str;

    /// 执行本工位业务(由具体工位实现;物流工位含重试熔断模拟)
    ///
    /// # 参数
    /// - `request`:业务流程执行请求 DTO
    ///
    /// # 返回
    /// - `Ok(ProcessResponseDto)`:业务执行成功
    /// - `Err(ProcessError)`:业务执行失败(可重试)
    fn execute_business(&self, request: &ProcessRequestDto) -> Result<ProcessResponseDto, ProcessError>;

    /// 在协调器上完成一次工位作业(条件变量同步流程的默认实现)
    ///
    /// 流程:① 等待本阶段条件就绪 → ② 执行本阶段业务 → ③ 标记完成并通知下游。
    ///
    /// # 参数
    /// - `coordinator`:阶段协调器(条件变量)
    /// - `request`:业务流程执行请求 DTO
    ///
    /// # 返回
    /// - `Ok(ProcessResponseDto)`:工位作业成功
    /// - `Err(ProcessError)`:业务执行失败(由调度器经重试熔断保护)
    fn perform(
        &self,
        coordinator: &dyn PhaseCoordinator,
        request: &ProcessRequestDto,
    ) -> Result<ProcessResponseDto, ProcessError> {
        // ① 在条件变量上等待本阶段可开工(条件不满足则挂起)
        coordinator.wait_until_ready(self.stage_index());
        self.logger().debug(&format!(
            "工位 {} / {} 已通过条件变量获准开工,开始执行业务",
            self.stage_id(),
            self.stage_name()
        ));
        // ② 执行本阶段业务(物流可能瞬时失败,返回 Err 触发重试熔断)
        let response = self.execute_business(request)?;
        // ③ 标记完成并通知等待线程(推进共享进度)
        coordinator.mark_complete();
        self.logger().info(&format!(
            "工位 {} / {} 作业完成,已通知下游工位",
            self.stage_id(),
            self.stage_name()
        ));
        Ok(response)
    }

    /// 获取统一日志对象(对应 ILogger<T>,由 DI 注入)
    ///
    /// # 返回
    /// 统一日志(`Arc<dyn Logger>`)
    fn logger(&self) -> Arc<dyn Logger>;
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : process_dtos.rs
//! DTO(数据传输对象)定义
//!
//! 用于跨层(表现层 → 接口层 → 应用层 → 领域层)传递数据,仅承载数据、无业务逻辑。
//! - `ProcessRequestDto`:业务流程执行请求
//! - `ProcessResponseDto`:业务流程执行响应

use crate::domain::entities::jewelry::Jewelry;

/// 业务流程执行请求 DTO
///
/// `department` / `operator` 为溯源扩展字段(预留给审计场景),
/// 当前演示中同事自行声明所属部门,未读取该两字段。
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct ProcessRequestDto {
    /// 流程类型标识(如 PROCUREMENT / DESIGN / PRODUCTION 等)
    pub process_type: String,
    /// 关联珠宝实体
    pub jewelry: Jewelry,
    /// 发起部门(如 采购部 / 设计部 / 生产部 等)
    pub department: String,
    /// 操作人(如 Mediator 中介者 / 具体岗位名称)
    pub operator: String,
}

impl ProcessRequestDto {
    /// 创建业务流程执行请求 DTO
    ///
    /// # 参数
    /// - `process_type`:流程类型标识
    /// - `jewelry`:关联珠宝
    /// - `department`:发起部门
    /// - `operator`:操作人
    ///
    /// # 返回
    /// 请求 DTO
    pub fn new(process_type: &str, jewelry: Jewelry, department: &str, operator: &str) -> Self {
        Self {
            process_type: process_type.to_string(),
            jewelry,
            department: department.to_string(),
            operator: operator.to_string(),
        }
    }
}

/// 业务流程执行响应 DTO
///
/// `instance_id` 预留给需要回传实例编号的上层调用方,演示中编号已写入日志。
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct ProcessResponseDto {
    /// 流程实例编号(如 PROCUREMENT-000001)
    pub instance_id: String,
    /// 流程名称(中文)
    pub process_name: String,
    /// 是否成功
    pub success: bool,
    /// 结果消息(成功摘要或失败原因)
    pub message: String,
}

impl ProcessResponseDto {
    /// 创建流程响应 DTO
    ///
    /// # 参数
    /// - `instance_id`:流程实例编号
    /// - `process_name`:流程名称
    /// - `success`:是否成功
    /// - `message`:结果消息
    ///
    /// # 返回
    /// 响应 DTO
    pub fn new(instance_id: &str, process_name: &str, success: bool, message: &str) -> Self {
        Self {
            instance_id: instance_id.to_string(),
            process_name: process_name.to_string(),
            success,
            message: message.to_string(),
        }
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : jewelry.rs
//! 珠宝行业领域实体定义
//!
//! 包含:
//! - `Jewelry`:珠宝业务实体(贯穿采购→设计→生产→质检→包装→物流→财务→
//!   营销→销售等全部流程)
//! - `ProcessOutcome`:业务流程执行产出(同事业务执行的返回载体)
//! - 全局自增流水号生成器(线程安全,用于生成唯一编号)

use std::sync::atomic::{AtomicU64, Ordering};

/// 全局自增流水号(线程安全,跨线程共享生成唯一序号)
static NEXT_SEQUENCE: AtomicU64 = AtomicU64::new(1);

/// 获取下一个业务流水号(原子递增,高并发安全)
///
/// # 返回
/// 下一个自增序号
pub fn next_sequence() -> u64 {
    NEXT_SEQUENCE.fetch_add(1, Ordering::SeqCst)
}

/// 珠宝业务实体(领域实体,跨全流程共享)
///
/// `id` / `status` / `with_status` 为领域状态演进预留(如 `PROCURED`→`DELIVERED`),
/// 当前演示以值传递共享珠宝实体,未对状态字段做持久化演进,属预留 API。
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct Jewelry {
    /// 珠宝编号(如 JWL-000001)
    pub id: String,
    /// 珠宝名称
    pub name: String,
    /// 材质(黄金 / 铂金 / 钻石 / K金 / 银)
    pub material: String,
    /// 重量(克)
    pub weight_grams: f64,
    /// 零售价(元)
    pub price: f64,
    /// 当前状态(INIT 初始 / PROCURED 已采购 / DESIGNED 已设计 /
    /// PRODUCED 已生产 / INSPECTED 已质检 / PACKED 已包装 / DELIVERED 已发货)
    pub status: String,
}

impl Jewelry {
    /// 创建珠宝实体
    ///
    /// # 参数
    /// - `name`:珠宝名称
    /// - `material`:材质
    /// - `weight_grams`:重量(克)
    /// - `price`:零售价(元)
    ///
    /// # 返回
    /// 初始状态为 `INIT` 的珠宝实体
    pub fn new(name: &str, material: &str, weight_grams: f64, price: f64) -> Self {
        Self {
            id: format!("JWL-{:06}", next_sequence()),
            name: name.to_string(),
            material: material.to_string(),
            weight_grams,
            price,
            status: "INIT".to_string(),
        }
    }

    /// 更新珠宝状态(返回新实体,保持不可变语义便于并发共享)
    ///
    /// # 参数
    /// - `status`:新状态
    ///
    /// # 返回
    /// 更新状态后的珠宝实体副本
    #[allow(dead_code)]
    pub fn with_status(&self, status: &str) -> Self {
        let mut cloned = self.clone();
        cloned.status = status.to_string();
        cloned
    }
}

/// 业务流程执行产出(同事业务执行的返回载体)
///
/// `instance_id` 预留给产出追溯使用,当前已写入执行记录(`ProcessRecord`),
/// 此处字段作为冗余追溯标识保留。
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct ProcessOutcome {
    /// 流程实例编号
    pub instance_id: String,
    /// 产出摘要(中文描述)
    pub summary: String,
    /// 是否成功
    pub success: bool,
}

impl ProcessOutcome {
    /// 创建成功产出
    ///
    /// # 参数
    /// - `instance_id`:流程实例编号
    /// - `summary`:产出摘要
    ///
    /// # 返回
    /// 成功产出
    pub fn success(instance_id: &str, summary: &str) -> Self {
        Self {
            instance_id: instance_id.to_string(),
            summary: summary.to_string(),
            success: true,
        }
    }

    /// 创建失败产出
    ///
    /// 预留 API:当前演示业务执行失败时直接返回错误,不构造失败产出;
    /// 该构造器预留给需要显式失败产出的场景。
    ///
    /// # 参数
    /// - `instance_id`:流程实例编号
    /// - `summary`:产出摘要
    ///
    /// # 返回
    /// 失败产出
    #[allow(dead_code)]
    pub fn failure(instance_id: &str, summary: &str) -> Self {
        Self {
            instance_id: instance_id.to_string(),
            summary: summary.to_string(),
            success: false,
        }
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : process_repository.rs
//! 业务流程仓储接口(领域层抽象,由基础设施层实现)
//!
//! 仓储用于持久化每次同事业务执行的记录,供统计与追溯使用。
//! 领域层只定义接口,具体存储(内存 / 数据库)由基础设施层按 DI 注入。

use crate::common::error::ProcessError;
use crate::domain::entities::jewelry::ProcessOutcome;

/// 业务流程执行记录(持久化载体)
#[derive(Debug, Clone)]
pub struct ProcessRecord {
    /// 流程实例编号
    pub instance_id: String,
    /// 流程名称(中文)
    pub process_name: String,
    /// 执行产出
    pub outcome: ProcessOutcome,
    /// 执行时间(格式:YYYY-MM-DD HH:MM:SS)
    pub executed_at: String,
}

/// 业务流程仓储抽象接口(线程安全)
pub trait ProcessRepository: Send + Sync {
    /// 保存业务执行记录
    ///
    /// # 参数
    /// - `record`:执行记录
    ///
    /// # 返回
    /// - `Ok(())`:保存成功
    /// - `Err(ProcessError)`:保存失败
    fn save(&self, record: ProcessRecord) -> Result<(), ProcessError>;

    /// 查询全部执行记录
    ///
    /// # 返回
    /// 全部执行记录
    fn find_all(&self) -> Vec<ProcessRecord>;

    /// 统计成功/失败数量
    ///
    /// # 返回
    /// `(成功数量, 失败数量)` 元组
    fn count(&self) -> (usize, usize);
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : container.rs
//! 依赖注入容器(组合根 Composition Root)
//!
//! 职责:集中装配(new)全部依赖并暴露访问方法,实现构造器注入。
//! - 统一日志(`Arc<dyn Logger>`)单例
//! - 重试 + 熔断适配器单例(`Arc<RetryCircuitBreaker>`)
//! - 12 个业务部门工位(StageWorker 子类)注册
//! - 内存仓储单例
//! - 业务流程应用服务(调度器)
//!
//! 依赖方向严格单向:presentation → interface → application → domain → common,
//! 基础设施层向上提供实现,由容器完成组装。

use std::sync::Arc;
use std::time::Duration;

use crate::application::condition::workers::{
    BusinessSalesWorker, DesignWorker, FinanceWorker, HrAdminWorker, InspectionWorker, ItWorker,
    LogisticsWorker, MarketingWorker, PackagingWorker, ProcurementWorker, ProductionWorker,
    TrainingWorker,
};
use crate::application::services::process_service::ProcessService;
use crate::common::logging::Logger;
use crate::common::resilience::retry_circuit_breaker::RetryCircuitBreaker;
use crate::domain::condition::worker::StageWorker;
use crate::infrastructure::logging::file_logger::FileLogger;
use crate::infrastructure::persistence::memory_process_repository::MemoryProcessRepository;

/// 依赖注入容器(组合根)
pub struct ServiceContainer {
    /// 统一日志(单例)
    logger: Arc<dyn Logger>,
    /// 重试 + 熔断适配器(单例)
    #[allow(dead_code)]
    resilience: Arc<RetryCircuitBreaker>,
    /// 内存仓储(单例,预留给扩展组件复用)
    #[allow(dead_code)]
    repository: Arc<MemoryProcessRepository>,
    /// 业务流程应用服务(调度器)
    service: Arc<ProcessService>,
}

impl ServiceContainer {
    /// 构建依赖注入容器(组合根,统一装配工位与全部服务)
    ///
    /// # 返回
    /// 已装配完成的容器实例
    pub fn new() -> Self {
        // 1. 基础设施依赖(单例)
        let logger: Arc<dyn Logger> = Arc::new(FileLogger::new("./Logs"));
        // 重试 2 次、连续失败 3 次熔断、冷却 5 秒
        let resilience = Arc::new(RetryCircuitBreaker::new(2, 3, Duration::from_secs(5)));
        let repository = Arc::new(MemoryProcessRepository::new());

        // 2. 创建 12 个业务部门工位(按供应链顺序注册)
        let workers: Vec<Arc<dyn StageWorker>> = vec![
            Arc::new(ProcurementWorker::new(logger.clone())),
            Arc::new(DesignWorker::new(logger.clone())),
            Arc::new(ProductionWorker::new(logger.clone())),
            Arc::new(InspectionWorker::new(logger.clone())),
            Arc::new(PackagingWorker::new(logger.clone())),
            Arc::new(LogisticsWorker::new(logger.clone())),
            Arc::new(FinanceWorker::new(logger.clone())),
            Arc::new(MarketingWorker::new(logger.clone())),
            Arc::new(BusinessSalesWorker::new(logger.clone())),
            Arc::new(HrAdminWorker::new(logger.clone())),
            Arc::new(ItWorker::new(logger.clone())),
            Arc::new(TrainingWorker::new(logger.clone())),
        ];

        // 3. 应用层服务(构造器注入)
        let service = Arc::new(ProcessService::new(
            workers,
            resilience.clone(),
            repository.clone(),
            logger.clone(),
        ));

        Self {
            logger,
            resilience,
            repository,
            service,
        }
    }

    /// 获取业务流程应用服务
    ///
    /// # 返回
    /// 应用服务(`Arc` 共享)
    pub fn service(&self) -> Arc<ProcessService> {
        self.service.clone()
    }

    /// 获取统一日志对象
    ///
    /// # 返回
    /// 统一日志(`Arc<dyn Logger>`)
    pub fn logger(&self) -> Arc<dyn Logger> {
        self.logger.clone()
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : file_logger.rs
//! 文件日志实现(按日期分文件夹、按日志等级分文件)
//!
//! 目录结构(示例,日期为当日):
//! ```text
//! Logs/
//!   2026-07-06/
//!     app-info.log
//!     app-error.log
//!     app-debug.log
//!     app-warn.log
//! ```
//!
//! 设计要点:
//! - **线程安全 / 高并发**:每个日志等级使用独立的 `Mutex<BufWriter<File>>`,
//!   同一等级写操作串行化,不同等级互不阻塞;可被 `Arc` 共享到多线程。
//! - **日期滚动**:每次写入检测日期目录,跨天自动切换到新的日期文件夹。
//! - **控制台与文件一致**:统一格式化 `[时间] [等级] 消息`,
//!   同时输出到控制台(stdout/stderr)与对应文件。

use std::fs::{self, File, OpenOptions};
use std::io::Write;
use std::path::PathBuf;
use std::sync::Mutex;

use crate::common::logging::{LogLevel, Logger};

/// 单日志等级的文件写入句柄(受互斥锁保护)
struct LevelWriter {
    /// 当前打开的缓冲写入器
    writer: Option<std::io::BufWriter<File>>,
    /// 该句柄对应的日期文件夹(用于跨天滚动判断)
    opened_date: String,
}

impl LevelWriter {
    /// 创建空的等级写入器
    fn new() -> Self {
        Self {
            writer: None,
            opened_date: String::new(),
        }
    }
}

/// 文件日志实现(线程安全、支持高并发写入)
pub struct FileLogger {
    /// 日志根目录(默认 ./Logs)
    base_dir: PathBuf,
    /// 调试日志写入器
    debug_writer: Mutex<LevelWriter>,
    /// 信息日志写入器
    info_writer: Mutex<LevelWriter>,
    /// 警告日志写入器
    warn_writer: Mutex<LevelWriter>,
    /// 错误日志写入器
    error_writer: Mutex<LevelWriter>,
}

impl FileLogger {
    /// 创建文件日志
    ///
    /// # 参数
    /// - `base_dir`:日志根目录(如 "./Logs")
    ///
    /// # 返回
    /// 文件日志实例
    pub fn new(base_dir: &str) -> Self {
        Self {
            base_dir: PathBuf::from(base_dir),
            debug_writer: Mutex::new(LevelWriter::new()),
            info_writer: Mutex::new(LevelWriter::new()),
            warn_writer: Mutex::new(LevelWriter::new()),
            error_writer: Mutex::new(LevelWriter::new()),
        }
    }

    /// 获取当前日期文件夹名(如 2026-07-06)
    ///
    /// # 返回
    /// 日期字符串
    fn date_folder(&self) -> String {
        chrono::Local::now().format("%Y-%m-%d").to_string()
    }

    /// 确保日期目录存在并返回目录路径
    ///
    /// # 参数
    /// - `date_folder`:日期文件夹名
    ///
    /// # 返回
    /// 日期目录路径
    fn ensure_dir(&self, date_folder: &str) -> PathBuf {
        let dir = self.base_dir.join(date_folder);
        let _ = fs::create_dir_all(&dir);
        dir
    }

    /// 以追加模式打开指定等级日志文件(返回缓冲写入器)
    ///
    /// # 参数
    /// - `level`:日志等级
    ///
    /// # 返回
    /// 缓冲写入器
    fn open_writer(&self, level: LogLevel) -> std::io::BufWriter<File> {
        let date_folder = self.date_folder();
        let dir = self.ensure_dir(&date_folder);
        let path = dir.join(level.file_name());
        let file = OpenOptions::new()
            .create(true)
            .append(true)
            .open(&path)
            .unwrap_or_else(|e| panic!("无法打开日志文件 {}:{}", path.display(), e));
        std::io::BufWriter::new(file)
    }

    /// 写入日志(统一格式;控制台与文件同时输出)
    ///
    /// # 参数
    /// - `level`:日志等级
    /// - `message`:日志消息
    fn write(&self, level: LogLevel, message: &str) {
        let timestamp = chrono::Local::now().format("%Y-%m-%d %H:%M:%S%.3f");
        let line = format!("[{}] [{}] {}", timestamp, level.tag(), message);

        // ① 输出到控制台(错误走 stderr,其余走 stdout)
        match level {
            LogLevel::Error => eprintln!("{}", line),
            _ => println!("{}", line),
        }

        // ② 输出到文件(按等级互斥锁串行化,保证线程安全)
        let target = match level {
            LogLevel::Debug => &self.debug_writer,
            LogLevel::Info => &self.info_writer,
            LogLevel::Warn => &self.warn_writer,
            LogLevel::Error => &self.error_writer,
        };
        let mut guard = target.lock().unwrap();
        let date_folder = self.date_folder();
        // 跨天或未打开 → 重新打开文件(实现按日期滚动)
        if guard.opened_date != date_folder || guard.writer.is_none() {
            guard.opened_date = date_folder.clone();
            guard.writer = Some(self.open_writer(level));
        }
        if let Some(writer) = guard.writer.as_mut() {
            let _ = writeln!(writer, "{}", line);
            let _ = writer.flush();
        }
    }
}

/// 实现统一日志接口(`Arc<dyn Logger>` 可注入各组件)
impl Logger for FileLogger {
    /// 输出调试日志
    fn debug(&self, message: &str) {
        self.write(LogLevel::Debug, message);
    }

    /// 输出信息日志
    fn info(&self, message: &str) {
        self.write(LogLevel::Info, message);
    }

    /// 输出警告日志
    fn warn(&self, message: &str) {
        self.write(LogLevel::Warn, message);
    }

    /// 输出错误日志
    fn error(&self, message: &str) {
        self.write(LogLevel::Error, message);
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : memory_process_repository.rs
//! 内存仓储实现(线程安全)
//!
//! 以 `Mutex<HashMap>` 实现 `ProcessRepository` 接口,供业务执行记录
//! 的保存、查询与统计使用。演示场景使用内存存储;生产环境可替换为数据库实现。

use std::collections::HashMap;
use std::sync::Mutex;

use crate::common::error::ProcessError;
use crate::domain::repository::process_repository::{ProcessRecord, ProcessRepository};

/// 内存仓储实现
pub struct MemoryProcessRepository {
    /// 内部存储(以流程实例编号为键,受互斥锁保护,保证并发安全)
    store: Mutex<HashMap<String, ProcessRecord>>,
}

impl MemoryProcessRepository {
    /// 创建内存仓储
    ///
    /// # 返回
    /// 内存仓储实例
    pub fn new() -> Self {
        Self {
            store: Mutex::new(HashMap::new()),
        }
    }
}

impl ProcessRepository for MemoryProcessRepository {
    /// 保存业务执行记录
    ///
    /// # 参数
    /// - `record`:执行记录
    ///
    /// # 返回
    /// - `Ok(())`:保存成功
    /// - `Err(ProcessError)`:保存失败
    fn save(&self, record: ProcessRecord) -> Result<(), ProcessError> {
        let mut store = self.store.lock().unwrap();
        store.insert(record.instance_id.clone(), record);
        Ok(())
    }

    /// 查询全部执行记录
    ///
    /// # 返回
    /// 全部执行记录
    fn find_all(&self) -> Vec<ProcessRecord> {
        let store = self.store.lock().unwrap();
        store.values().cloned().collect()
    }

    /// 统计成功/失败数量
    ///
    /// # 返回
    /// `(成功数量, 失败数量)` 元组
    fn count(&self) -> (usize, usize) {
        let store = self.store.lock().unwrap();
        let total = store.values().len();
        let success = store.values().filter(|r| r.outcome.success).count();
        (success, total - success)
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : contracts.rs
//! 对外交互契约(Contracts)
//!
//! 定义外部调用方与系统交互的统一契约结构(业务信封),
//! 承载「工位标识 + 执行请求」,供表现层/外部系统装配。

use crate::domain::dtos::process_dtos::ProcessRequestDto;

/// 业务信封(外部派发一个工位作业的载体)
#[derive(Debug, Clone)]
pub struct BusinessEnvelope {
    /// 工位标识(如 PROCUREMENT / TRAINING)
    pub stage_id: String,
    /// 执行请求 DTO
    pub request: ProcessRequestDto,
}

impl BusinessEnvelope {
    /// 创建业务信封
    ///
    /// # 参数
    /// - `stage_id`:工位标识
    /// - `request`:执行请求
    ///
    /// # 返回
    /// 业务信封
    pub fn new(stage_id: &str, request: ProcessRequestDto) -> Self {
        Self {
            stage_id: stage_id.to_string(),
            request,
        }
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : ports.rs
//! 对外 API 端口契约(Ports)
//!
//! 定义表现层(presentation)与外部调用方可消费的应用端口,
//! 将「应用能力」与「具体实现」解耦;具体实现由表现层/应用层提供。
//!
//! 条件变量模式语义:外部通过「派发工位标识」触发该工位在独立条件变量
//! 生产线上完成一次作业(等待条件 → 执行业务 → 通知)。

use crate::common::error::ProcessError;
use crate::domain::dtos::process_dtos::{ProcessRequestDto, ProcessResponseDto};
use crate::domain::repository::process_repository::ProcessRecord;

/// 对外应用 API 端口契约(线程安全)
///
/// 表现层实现该端口并向外部暴露;外部仅依赖本端口,不依赖具体实现。
pub trait BusinessApiPort: Send + Sync {
    /// 派发执行指定工位作业(创建独立条件变量生产线并执行)
    ///
    /// # 参数
    /// - `stage_id`:工位标识(如 PROCUREMENT / TRAINING)
    /// - `request`:执行请求 DTO
    ///
    /// # 返回
    /// - `Ok(ProcessResponseDto)`:工位执行响应
    /// - `Err(ProcessError)`:派发/执行失败
    fn dispatch(
        &self,
        stage_id: &str,
        request: ProcessRequestDto,
    ) -> Result<ProcessResponseDto, ProcessError>;

    /// 获取业务执行统计(成功数量,失败数量)
    ///
    /// # 返回
    /// `(成功数量, 失败数量)` 元组
    fn statistics(&self) -> (usize, usize);

    /// 获取全部业务执行记录(用于追溯/汇总展示)
    ///
    /// # 返回
    /// 全部执行记录
    fn records(&self) -> Vec<ProcessRecord>;
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : controller.rs
//! 应用控制器(表现层,控制台入口)
//!
//! 职责:
//! - 从组合根(DI 容器)获取应用服务与统一日志
//! - 实现 `interface::ports::BusinessApiPort` 端口契约(对外 API)
//! - 创建贯穿全流程的珠宝实体,驱动条件变量顺序调度与并发调度演示
//! - 输出业务执行统计与记录汇总
//!
//! 依赖方向:presentation → interface → application → domain → common,
//! 符合严格分层(六层结构)。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::dtos::process_dtos::{ProcessRequestDto, ProcessResponseDto};
use crate::domain::entities::jewelry::Jewelry;
use crate::domain::repository::process_repository::ProcessRecord;
use crate::infrastructure::di::container::ServiceContainer;
use crate::interface::contracts::BusinessEnvelope;
use crate::interface::ports::BusinessApiPort;

/// 应用控制器(控制台表现层,实现对外端口契约)
pub struct ApplicationController {
    /// 依赖注入容器(组合根)
    container: Arc<ServiceContainer>,
    /// 统一日志对象
    logger: Arc<dyn Logger>,
}

impl ApplicationController {
    /// 创建应用控制器
    ///
    /// # 参数
    /// - `container`:依赖注入容器
    ///
    /// # 返回
    /// 应用控制器实例
    pub fn new(container: Arc<ServiceContainer>) -> Self {
        let logger = container.logger();
        Self { container, logger }
    }

    /// 启动珠宝行业全程业务流程(条件变量模式)演示
    ///
    /// 流程:
    /// ① 打印标题与配置
    /// ② 创建珠宝实体
    /// ③ 条件变量顺序调度(按供应链逐个工位经条件变量同步执行)
    /// ④ 输出执行统计与记录明细
    /// ⑤ 条件变量并发调度(12 个工位线程通过条件变量流水线同步)
    /// ⑥ 通过端口契约派发单个工位
    pub fn run(&self) {
        // ① 标题与运行说明
        self.logger.info("================================================================");
        self.logger.info("   条件变量模式 Condition Variable Pattern");
        self.logger.info("   珠宝行业企业级全程业务流程(DDD 六层分层 · 同步型并发模式)");
        self.logger.info("   业务:原料采购核验 · 设计制图 · 加工生产 · 质检 · 包装 · 物流");
        self.logger.info("        · 财务 · 营销推广 · 业务销售 · 人事行政 · IT · 培训");
        self.logger.info("   日志:Logs/<日期>/app-{info,error,debug,warn}.log(按日期/等级分文件)");
        self.logger.info("================================================================");

        // ② 创建贯穿全流程的珠宝实体
        let jewelry = Jewelry::new("六福传承金镯", "黄金", 35.68, 26800.0);
        self.logger.info(&format!(
            "创建珠宝实体:{},材质={},重量={} 克,零售价={} 元",
            jewelry.name, jewelry.material, jewelry.weight_grams, jewelry.price
        ));

        // ③ 条件变量顺序调度:按供应链逐个工位经条件变量同步执行
        let request = ProcessRequestDto::new("ALL", jewelry.clone(), "调度中心", "CondVar");
        self.container.service().run_sequential(request);
        self.logger.info("================================================================");

        // ④ 输出执行统计(读取内存仓储)
        self.print_summary();

        // ⑤ 条件变量并发调度(高并发流水线同步演示)
        self.logger.info("【高并发演示】条件变量并发调度:12 个工位线程经条件变量流水线同步……");
        let concurrent_request =
            ProcessRequestDto::new("ALL", jewelry.clone(), "调度中心", "Concurrent");
        self.container.service().run_concurrent(concurrent_request);
        self.print_summary();

        // ⑥ 通过端口契约派发单个工位(BusinessEnvelope + dispatch)
        let envelope = BusinessEnvelope::new(
            "TRAINING",
            ProcessRequestDto::new("TRAINING", jewelry, "培训部", "PortTest"),
        );
        match self.dispatch(&envelope.stage_id, envelope.request) {
            Ok(resp) => self.logger.info(&format!(
                "端口契约派发工位成功:{} / {}",
                resp.process_name, resp.message
            )),
            Err(err) => self.logger.warn(&format!("端口契约派发工位失败:{}", err)),
        }

        // ⑦ 输出已注册工位清单
        let workers = self.container.service().workers();
        self.logger
            .info(&format!("已注册工位数:{}", workers.len()));
        for worker in workers {
            self.logger.info(&format!(
                "  - [{}] {} / {}",
                worker.stage_id(),
                worker.stage_name(),
                worker.stage_index()
            ));
        }
        self.logger.info("================================================================");
    }

    /// 输出执行统计与记录明细(基于仓储数据)
    fn print_summary(&self) {
        let (success, failure) = self.statistics();
        self.logger.info(&format!(
            "业务调度汇总:成功 {} 项,失败 {} 项(详见当日日志目录)",
            success, failure
        ));
        let records = self.records();
        self.logger.info(&format!("执行记录明细(共 {} 条):", records.len()));
        for record in records {
            let flag = if record.outcome.success { "成功" } else { "失败" };
            self.logger.info(&format!(
                "  - {} | {} | 状态:{} | 时间:{}",
                record.instance_id, record.process_name, flag, record.executed_at
            ));
        }
    }
}

/// 实现对外 API 端口契约(interface 层定义)
impl BusinessApiPort for ApplicationController {
    /// 派发执行指定工位作业(创建独立条件变量生产线并执行)
    fn dispatch(
        &self,
        stage_id: &str,
        request: ProcessRequestDto,
    ) -> Result<ProcessResponseDto, ProcessError> {
        self.container.service().dispatch(stage_id, request)
    }

    /// 获取业务执行统计(成功数量,失败数量)
    fn statistics(&self) -> (usize, usize) {
        self.container.service().statistics()
    }

    /// 获取全部业务执行记录(用于追溯/汇总展示)
    fn records(&self) -> Vec<ProcessRecord> {
        self.container.service().records()
    }
}

//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : business_sales.rs
//! 销售工位(业务销售,阶段 8)
//!
//! 条件变量模式中的「工位」:等待营销工位完成(条件就绪)后执行业务销售,
//! 完成并通知下游人事行政工位。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::condition::worker::StageWorker;
use crate::domain::dtos::process_dtos::{ProcessRequestDto, ProcessResponseDto};
use crate::domain::entities::jewelry::next_sequence;

/// 销售工位
pub struct BusinessSalesWorker {
    /// 统一日志对象(DI 注入)
    logger: Arc<dyn Logger>,
}

impl BusinessSalesWorker {
    /// 创建销售工位
    ///
    /// # 参数
    /// - `logger`:统一日志
    ///
    /// # 返回
    /// 销售工位实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self { logger }
    }
}

impl StageWorker for BusinessSalesWorker {
    /// 获取工位阶段序号(供应链第 8 位)
    fn stage_index(&self) -> usize {
        8
    }

    /// 获取工位标识
    fn stage_id(&self) -> &str {
        "SALES"
    }

    /// 获取工位名称
    fn stage_name(&self) -> &str {
        "销售部"
    }

    /// 执行业务销售业务
    fn execute_business(&self, request: &ProcessRequestDto) -> Result<ProcessResponseDto, ProcessError> {
        self.logger.info(&format!(
            "【销售工位】执行业务销售:{}",
            request.jewelry.name
        ));
        let instance_id = format!("{}-{:06}", self.stage_id(), next_sequence());
        let message = "业务销售完成,门店成交 + 订单履约 + 会员服务";
        self.logger.info(&format!("【销售工位】{}", message));
        Ok(ProcessResponseDto::new(&instance_id, self.stage_name(), true, message))
    }

    /// 获取统一日志对象
    fn logger(&self) -> Arc<dyn Logger> {
        self.logger.clone()
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : design.rs
//! 设计工位(设计制图,阶段 1)
//!
//! 条件变量模式中的「工位」:等待采购工位完成(条件就绪)后执行设计制图,
//! 完成并通知下游生产工位。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::condition::worker::StageWorker;
use crate::domain::dtos::process_dtos::{ProcessRequestDto, ProcessResponseDto};
use crate::domain::entities::jewelry::next_sequence;

/// 设计工位
pub struct DesignWorker {
    /// 统一日志对象(DI 注入)
    logger: Arc<dyn Logger>,
}

impl DesignWorker {
    /// 创建设计工位
    ///
    /// # 参数
    /// - `logger`:统一日志
    ///
    /// # 返回
    /// 设计工位实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self { logger }
    }
}

impl StageWorker for DesignWorker {
    /// 获取工位阶段序号(供应链第 1 位)
    fn stage_index(&self) -> usize {
        1
    }

    /// 获取工位标识
    fn stage_id(&self) -> &str {
        "DESIGN"
    }

    /// 获取工位名称
    fn stage_name(&self) -> &str {
        "设计部"
    }

    /// 执行设计制图业务
    fn execute_business(&self, request: &ProcessRequestDto) -> Result<ProcessResponseDto, ProcessError> {
        self.logger.info(&format!(
            "【设计工位】执行设计制图:{}",
            request.jewelry.name
        ));
        let instance_id = format!("{}-{:06}", self.stage_id(), next_sequence());
        let message = "设计制图完成,3D 起版 + 工艺标注,设计稿已归档";
        self.logger.info(&format!("【设计工位】{}", message));
        Ok(ProcessResponseDto::new(&instance_id, self.stage_name(), true, message))
    }

    /// 获取统一日志对象
    fn logger(&self) -> Arc<dyn Logger> {
        self.logger.clone()
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : finance.rs
//! 财务工位(财务核算,阶段 6)
//!
//! 条件变量模式中的「工位」:等待物流工位完成(条件就绪)后执行财务核算,
//! 完成并通知下游营销工位。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::condition::worker::StageWorker;
use crate::domain::dtos::process_dtos::{ProcessRequestDto, ProcessResponseDto};
use crate::domain::entities::jewelry::next_sequence;

/// 财务工位
pub struct FinanceWorker {
    /// 统一日志对象(DI 注入)
    logger: Arc<dyn Logger>,
}

impl FinanceWorker {
    /// 创建财务工位
    ///
    /// # 参数
    /// - `logger`:统一日志
    ///
    /// # 返回
    /// 财务工位实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self { logger }
    }
}

impl StageWorker for FinanceWorker {
    /// 获取工位阶段序号(供应链第 6 位)
    fn stage_index(&self) -> usize {
        6
    }

    /// 获取工位标识
    fn stage_id(&self) -> &str {
        "FINANCE"
    }

    /// 获取工位名称
    fn stage_name(&self) -> &str {
        "财务部"
    }

    /// 执行财务核算业务
    fn execute_business(&self, request: &ProcessRequestDto) -> Result<ProcessResponseDto, ProcessError> {
        self.logger.info(&format!(
            "【财务工位】执行财务核算:{}(零售价:{} 元)",
            request.jewelry.name, request.jewelry.price
        ));
        let instance_id = format!("{}-{:06}", self.stage_id(), next_sequence());
        let message = format!(
            "财务核算完成,成本入账 + 开具发票 + 资金结算(售价 {} 元)",
            request.jewelry.price
        );
        self.logger.info(&format!("【财务工位】{}", message));
        Ok(ProcessResponseDto::new(&instance_id, self.stage_name(), true, &message))
    }

    /// 获取统一日志对象
    fn logger(&self) -> Arc<dyn Logger> {
        self.logger.clone()
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : hr_admin.rs
//! 人事行政工位(人事行政,阶段 9)
//!
//! 条件变量模式中的「工位」:等待销售工位完成(条件就绪)后执行人事行政,
//! 完成并通知下游 IT 工位。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::condition::worker::StageWorker;
use crate::domain::dtos::process_dtos::{ProcessRequestDto, ProcessResponseDto};
use crate::domain::entities::jewelry::next_sequence;

/// 人事行政工位
pub struct HrAdminWorker {
    /// 统一日志对象(DI 注入)
    logger: Arc<dyn Logger>,
}

impl HrAdminWorker {
    /// 创建人事行政工位
    ///
    /// # 参数
    /// - `logger`:统一日志
    ///
    /// # 返回
    /// 人事行政工位实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self { logger }
    }
}

impl StageWorker for HrAdminWorker {
    /// 获取工位阶段序号(供应链第 9 位)
    fn stage_index(&self) -> usize {
        9
    }

    /// 获取工位标识
    fn stage_id(&self) -> &str {
        "HR_ADMIN"
    }

    /// 获取工位名称
    fn stage_name(&self) -> &str {
        "人事行政部"
    }

    /// 执行人事行政业务
    fn execute_business(&self, request: &ProcessRequestDto) -> Result<ProcessResponseDto, ProcessError> {
        self.logger.info(&format!(
            "【人事行政工位】执行人事行政保障:{}",
            request.jewelry.name
        ));
        let instance_id = format!("{}-{:06}", self.stage_id(), next_sequence());
        let message = "人事行政完成,员工考勤 + 薪酬核算 + 行政保障";
        self.logger.info(&format!("【人事行政工位】{}", message));
        Ok(ProcessResponseDto::new(&instance_id, self.stage_name(), true, message))
    }

    /// 获取统一日志对象
    fn logger(&self) -> Arc<dyn Logger> {
        self.logger.clone()
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : inspection.rs
//! 质检工位(质量检测,阶段 3)
//!
//! 条件变量模式中的「工位」:等待生产工位完成(条件就绪)后执行质量检测,
//! 完成并通知下游包装工位。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::condition::worker::StageWorker;
use crate::domain::dtos::process_dtos::{ProcessRequestDto, ProcessResponseDto};
use crate::domain::entities::jewelry::next_sequence;

/// 质检工位
pub struct InspectionWorker {
    /// 统一日志对象(DI 注入)
    logger: Arc<dyn Logger>,
}

impl InspectionWorker {
    /// 创建质检工位
    ///
    /// # 参数
    /// - `logger`:统一日志
    ///
    /// # 返回
    /// 质检工位实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self { logger }
    }
}

impl StageWorker for InspectionWorker {
    /// 获取工位阶段序号(供应链第 3 位)
    fn stage_index(&self) -> usize {
        3
    }

    /// 获取工位标识
    fn stage_id(&self) -> &str {
        "INSPECTION"
    }

    /// 获取工位名称
    fn stage_name(&self) -> &str {
        "质检部"
    }

    /// 执行质量检测业务
    fn execute_business(&self, request: &ProcessRequestDto) -> Result<ProcessResponseDto, ProcessError> {
        self.logger.info(&format!(
            "【质检工位】执行质量检测:{}",
            request.jewelry.name
        ));
        let instance_id = format!("{}-{:06}", self.stage_id(), next_sequence());
        let message = "质检完成,成色/重量复核 + 工艺抽检合格,出具鉴定证书";
        self.logger.info(&format!("【质检工位】{}", message));
        Ok(ProcessResponseDto::new(&instance_id, self.stage_name(), true, message))
    }

    /// 获取统一日志对象
    fn logger(&self) -> Arc<dyn Logger> {
        self.logger.clone()
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : it.rs
//! IT 工位(信息系统运维,阶段 10)
//!
//! 条件变量模式中的「工位」:等待人事行政工位完成(条件就绪)后执行 IT 运维,
//! 完成并通知下游培训工位。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::condition::worker::StageWorker;
use crate::domain::dtos::process_dtos::{ProcessRequestDto, ProcessResponseDto};
use crate::domain::entities::jewelry::next_sequence;

/// IT 工位
pub struct ItWorker {
    /// 统一日志对象(DI 注入)
    logger: Arc<dyn Logger>,
}

impl ItWorker {
    /// 创建 IT 工位
    ///
    /// # 参数
    /// - `logger`:统一日志
    ///
    /// # 返回
    /// IT 工位实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self { logger }
    }
}

impl StageWorker for ItWorker {
    /// 获取工位阶段序号(供应链第 10 位)
    fn stage_index(&self) -> usize {
        10
    }

    /// 获取工位标识
    fn stage_id(&self) -> &str {
        "IT"
    }

    /// 获取工位名称
    fn stage_name(&self) -> &str {
        "IT 信息部"
    }

    /// 执行信息系统运维业务
    fn execute_business(&self, request: &ProcessRequestDto) -> Result<ProcessResponseDto, ProcessError> {
        self.logger.info(&format!(
            "【IT 工位】执行系统运维保障:{}",
            request.jewelry.name
        ));
        let instance_id = format!("{}-{:06}", self.stage_id(), next_sequence());
        let message = "IT 运维完成,ERP 系统 + 数据安全 + 网络保障";
        self.logger.info(&format!("【IT 工位】{}", message));
        Ok(ProcessResponseDto::new(&instance_id, self.stage_name(), true, message))
    }

    /// 获取统一日志对象
    fn logger(&self) -> Arc<dyn Logger> {
        self.logger.clone()
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : logistics.rs
//! 物流工位(仓储物流配送,阶段 5)
//!
//! 条件变量模式中的「工位」:等待包装工位完成(条件就绪)后执行物流配送,
//! 完成并通知下游财务工位。
//!
//! 重试熔断演示:通过静态计数模拟前两次「外部物流系统瞬时不可用」,
//! 返回错误触发调度器「重试 + 熔断」适配器重试,第 3 次成功(warn 记录)。

use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::condition::worker::StageWorker;
use crate::domain::dtos::process_dtos::{ProcessRequestDto, ProcessResponseDto};
use crate::domain::entities::jewelry::next_sequence;

/// 外部物流系统调用计数器(静态、跨调用累加,用于演示瞬时失败后恢复)
static LOGISTICS_CALL_COUNT: AtomicU32 = AtomicU32::new(0);

/// 物流工位
pub struct LogisticsWorker {
    /// 统一日志对象(DI 注入)
    logger: Arc<dyn Logger>,
}

impl LogisticsWorker {
    /// 创建物流工位
    ///
    /// # 参数
    /// - `logger`:统一日志
    ///
    /// # 返回
    /// 物流工位实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self { logger }
    }

    /// 模拟调用外部物流系统(前两次返回瞬时失败,第三次成功)
    ///
    /// # 参数
    /// - `request`:业务流程执行请求
    ///
    /// # 返回
    /// - `Ok(String)`:物流成功消息
    /// - `Err(ProcessError)`:外部系统瞬时不可用
    fn call_external_logistics(&self, request: &ProcessRequestDto) -> Result<String, ProcessError> {
        let count = LOGISTICS_CALL_COUNT.fetch_add(1, Ordering::SeqCst) + 1;
        if count <= 2 {
            // 前两次模拟外部物流系统暂时不可用,触发重试
            self.logger.warn(&format!(
                "【物流工位】外部物流系统暂时不可用(第 {} 次尝试)",
                count
            ));
            return Err(ProcessError::new(
                "EXTERNAL_LOGISTICS_UNAVAILABLE",
                "外部物流系统暂时不可用,请重试",
            ));
        }
        // 第三次调用成功
        Ok(format!(
            "物流配送完成,{} 保价发货 + 在途跟踪 + 签收确认",
            request.jewelry.name
        ))
    }
}

impl StageWorker for LogisticsWorker {
    /// 获取工位阶段序号(供应链第 5 位)
    fn stage_index(&self) -> usize {
        5
    }

    /// 获取工位标识
    fn stage_id(&self) -> &str {
        "LOGISTICS"
    }

    /// 获取工位名称
    fn stage_name(&self) -> &str {
        "物流部"
    }

    /// 执行物流配送业务(可能瞬时失败,触发重试熔断)
    fn execute_business(&self, request: &ProcessRequestDto) -> Result<ProcessResponseDto, ProcessError> {
        self.logger.info(&format!(
            "【物流工位】执行物流配送:{}",
            request.jewelry.name
        ));
        let instance_id = format!("{}-{:06}", self.stage_id(), next_sequence());
        // 调用外部物流系统(可能瞬时失败,返回 Err 触发重试熔断)
        let message = self.call_external_logistics(request)?;
        self.logger.info(&format!("【物流工位】{}", message));
        Ok(ProcessResponseDto::new(&instance_id, self.stage_name(), true, &message))
    }

    /// 获取统一日志对象
    fn logger(&self) -> Arc<dyn Logger> {
        self.logger.clone()
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : marketing.rs
//! 营销工位(营销推广,阶段 7)
//!
//! 条件变量模式中的「工位」:等待财务工位完成(条件就绪)后执行营销推广,
//! 完成并通知下游销售工位。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::condition::worker::StageWorker;
use crate::domain::dtos::process_dtos::{ProcessRequestDto, ProcessResponseDto};
use crate::domain::entities::jewelry::next_sequence;

/// 营销工位
pub struct MarketingWorker {
    /// 统一日志对象(DI 注入)
    logger: Arc<dyn Logger>,
}

impl MarketingWorker {
    /// 创建营销工位
    ///
    /// # 参数
    /// - `logger`:统一日志
    ///
    /// # 返回
    /// 营销工位实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self { logger }
    }
}

impl StageWorker for MarketingWorker {
    /// 获取工位阶段序号(供应链第 7 位)
    fn stage_index(&self) -> usize {
        7
    }

    /// 获取工位标识
    fn stage_id(&self) -> &str {
        "MARKETING"
    }

    /// 获取工位名称
    fn stage_name(&self) -> &str {
        "营销部"
    }

    /// 执行营销推广业务
    fn execute_business(&self, request: &ProcessRequestDto) -> Result<ProcessResponseDto, ProcessError> {
        self.logger.info(&format!(
            "【营销工位】执行营销推广:{}",
            request.jewelry.name
        ));
        let instance_id = format!("{}-{:06}", self.stage_id(), next_sequence());
        let message = "营销推广完成,广告投放 + 渠道推广 + 品牌种草";
        self.logger.info(&format!("【营销工位】{}", message));
        Ok(ProcessResponseDto::new(&instance_id, self.stage_name(), true, message))
    }

    /// 获取统一日志对象
    fn logger(&self) -> Arc<dyn Logger> {
        self.logger.clone()
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : packaging.rs
//! 包装工位(成品包装,阶段 4)
//!
//! 条件变量模式中的「工位」:等待质检工位完成(条件就绪)后执行成品包装,
//! 完成并通知下游物流工位。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::condition::worker::StageWorker;
use crate::domain::dtos::process_dtos::{ProcessRequestDto, ProcessResponseDto};
use crate::domain::entities::jewelry::next_sequence;

/// 包装工位
pub struct PackagingWorker {
    /// 统一日志对象(DI 注入)
    logger: Arc<dyn Logger>,
}

impl PackagingWorker {
    /// 创建包装工位
    ///
    /// # 参数
    /// - `logger`:统一日志
    ///
    /// # 返回
    /// 包装工位实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self { logger }
    }
}

impl StageWorker for PackagingWorker {
    /// 获取工位阶段序号(供应链第 4 位)
    fn stage_index(&self) -> usize {
        4
    }

    /// 获取工位标识
    fn stage_id(&self) -> &str {
        "PACKAGING"
    }

    /// 获取工位名称
    fn stage_name(&self) -> &str {
        "包装部"
    }

    /// 执行成品包装业务
    fn execute_business(&self, request: &ProcessRequestDto) -> Result<ProcessResponseDto, ProcessError> {
        self.logger.info(&format!(
            "【包装工位】执行成品包装:{}",
            request.jewelry.name
        ));
        let instance_id = format!("{}-{:06}", self.stage_id(), next_sequence());
        let message = "包装完成,礼盒装配 + 防伪标签 + 出库单已生成";
        self.logger.info(&format!("【包装工位】{}", message));
        Ok(ProcessResponseDto::new(&instance_id, self.stage_name(), true, message))
    }

    /// 获取统一日志对象
    fn logger(&self) -> Arc<dyn Logger> {
        self.logger.clone()
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : procurement.rs
//! 采购工位(原料采购核验,阶段 0)
//!
//! 条件变量模式中的「工位」:在条件变量上等待本阶段可开工,
//! 执行原料采购核验业务后标记完成并通知下游设计工位。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::condition::worker::StageWorker;
use crate::domain::dtos::process_dtos::{ProcessRequestDto, ProcessResponseDto};
use crate::domain::entities::jewelry::next_sequence;

/// 采购工位
pub struct ProcurementWorker {
    /// 统一日志对象(DI 注入)
    logger: Arc<dyn Logger>,
}

impl ProcurementWorker {
    /// 创建采购工位
    ///
    /// # 参数
    /// - `logger`:统一日志
    ///
    /// # 返回
    /// 采购工位实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self { logger }
    }
}

impl StageWorker for ProcurementWorker {
    /// 获取工位阶段序号(供应链第 0 位)
    fn stage_index(&self) -> usize {
        0
    }

    /// 获取工位标识
    fn stage_id(&self) -> &str {
        "PROCUREMENT"
    }

    /// 获取工位名称
    fn stage_name(&self) -> &str {
        "采购部"
    }

    /// 执行原料采购核验业务
    fn execute_business(&self, request: &ProcessRequestDto) -> Result<ProcessResponseDto, ProcessError> {
        self.logger.info(&format!(
            "【采购工位】执行原料采购核验:{}(材质:{})",
            request.jewelry.name, request.jewelry.material
        ));
        let instance_id = format!("{}-{:06}", self.stage_id(), next_sequence());
        let message = "采购核验完成,成色/重量核验 + 供应商资质,验收入库";
        self.logger.info(&format!("【采购工位】{}", message));
        Ok(ProcessResponseDto::new(&instance_id, self.stage_name(), true, message))
    }

    /// 获取统一日志对象
    fn logger(&self) -> Arc<dyn Logger> {
        self.logger.clone()
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : production.rs
//! 生产工位(加工生产,阶段 2)
//!
//! 条件变量模式中的「工位」:等待设计工位完成(条件就绪)后执行加工生产,
//! 完成并通知下游质检工位。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::condition::worker::StageWorker;
use crate::domain::dtos::process_dtos::{ProcessRequestDto, ProcessResponseDto};
use crate::domain::entities::jewelry::next_sequence;

/// 生产工位
pub struct ProductionWorker {
    /// 统一日志对象(DI 注入)
    logger: Arc<dyn Logger>,
}

impl ProductionWorker {
    /// 创建生产工位
    ///
    /// # 参数
    /// - `logger`:统一日志
    ///
    /// # 返回
    /// 生产工位实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self { logger }
    }
}

impl StageWorker for ProductionWorker {
    /// 获取工位阶段序号(供应链第 2 位)
    fn stage_index(&self) -> usize {
        2
    }

    /// 获取工位标识
    fn stage_id(&self) -> &str {
        "PRODUCTION"
    }

    /// 获取工位名称
    fn stage_name(&self) -> &str {
        "生产部"
    }

    /// 执行加工生产业务
    fn execute_business(&self, request: &ProcessRequestDto) -> Result<ProcessResponseDto, ProcessError> {
        self.logger.info(&format!(
            "【生产工位】执行加工生产:{}(重量:{} 克)",
            request.jewelry.name, request.jewelry.weight_grams
        ));
        let instance_id = format!("{}-{:06}", self.stage_id(), next_sequence());
        let message = "加工生产完成,CNC 执模 + 镶嵌 + 抛光,成品下线";
        self.logger.info(&format!("【生产工位】{}", message));
        Ok(ProcessResponseDto::new(&instance_id, self.stage_name(), true, message))
    }

    /// 获取统一日志对象
    fn logger(&self) -> Arc<dyn Logger> {
        self.logger.clone()
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : training.rs
//! 培训工位(人才培训,阶段 11)
//!
//! 条件变量模式中的「工位」:等待 IT 工位完成(条件就绪)后执行人才培训,
//! 完成并通知(流水线末端,无下游)。

use std::sync::Arc;

use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::domain::condition::worker::StageWorker;
use crate::domain::dtos::process_dtos::{ProcessRequestDto, ProcessResponseDto};
use crate::domain::entities::jewelry::next_sequence;

/// 培训工位
pub struct TrainingWorker {
    /// 统一日志对象(DI 注入)
    logger: Arc<dyn Logger>,
}

impl TrainingWorker {
    /// 创建培训工位
    ///
    /// # 参数
    /// - `logger`:统一日志
    ///
    /// # 返回
    /// 培训工位实例
    pub fn new(logger: Arc<dyn Logger>) -> Self {
        Self { logger }
    }
}

impl StageWorker for TrainingWorker {
    /// 获取工位阶段序号(供应链第 11 位,末端)
    fn stage_index(&self) -> usize {
        11
    }

    /// 获取工位标识
    fn stage_id(&self) -> &str {
        "TRAINING"
    }

    /// 获取工位名称
    fn stage_name(&self) -> &str {
        "培训部"
    }

    /// 执行人才培训业务
    fn execute_business(&self, request: &ProcessRequestDto) -> Result<ProcessResponseDto, ProcessError> {
        self.logger.info(&format!(
            "【培训工位】执行人才培训:{}",
            request.jewelry.name
        ));
        let instance_id = format!("{}-{:06}", self.stage_id(), next_sequence());
        let message = "培训完成,技能培训 + 考核评估 + 档案归档";
        self.logger.info(&format!("【培训工位】{}", message));
        Ok(ProcessResponseDto::new(&instance_id, self.stage_name(), true, message))
    }

    /// 获取统一日志对象
    fn logger(&self) -> Arc<dyn Logger> {
        self.logger.clone()
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : condition_line.rs
//! 条件变量生产线(Condition Variable Production Line)
//!
//! 条件变量模式的典型实现:用 `Mutex<ProductionState>` 保护共享进度,
//! 配合 `Condvar` 实现工位线程之间的「等待条件 → 通知唤醒」同步。
//!
//! - `wait_until_ready`:工位持锁检查条件,不满足则 `wait_while` 挂起并自动
//!   释放锁,被 `notify_all` 唤醒后自动重新检查条件(规避虚假唤醒)。
//! - `mark_complete`:完成一个阶段后推进共享进度并 `notify_all` 唤醒全部
//!   等待线程,等待线程经条件重检查仅满足者继续,形成严格上下游同步。

use std::sync::{Arc, Condvar, Mutex};

use crate::common::logging::Logger;
use crate::domain::condition::coordinator::PhaseCoordinator;
use crate::domain::condition::state::ProductionState;

/// 条件变量生产线(阶段协调器的具体实现)
pub struct ConditionVariableLine {
    /// 共享生产进度状态(受互斥锁保护)
    state: Mutex<ProductionState>,
    /// 条件变量(等待/通知原语)
    condvar: Condvar,
    /// 流水线总阶段数
    total_phases: usize,
    /// 统一日志对象(DI 注入)
    logger: Arc<dyn Logger>,
}

impl ConditionVariableLine {
    /// 创建条件变量生产线
    ///
    /// # 参数
    /// - `total_phases`:总阶段数(12 个业务部门)
    /// - `jewelry_name`:当前加工珠宝名称
    /// - `logger`:统一日志
    ///
    /// # 返回
    /// 条件变量生产线实例
    pub fn new(total_phases: usize, jewelry_name: &str, logger: Arc<dyn Logger>) -> Self {
        Self {
            state: Mutex::new(ProductionState::new(jewelry_name)),
            condvar: Condvar::new(),
            total_phases,
            logger,
        }
    }

    /// 预置共享进度到指定阶段(表示该工位所有上游已全部完成)
    ///
    /// 用于「单独派发单个工位」场景:被派发工位无需等待上游,直接获准开工。
    ///
    /// # 参数
    /// - `target_phase`:目标进度(等于被派发工位的阶段序号)
    pub fn advance_to(&self, target_phase: usize) {
        let mut guard = self.state.lock().unwrap();
        guard.current_phase = target_phase;
    }
}

/// 实现阶段协调器抽象接口(条件变量同步原语)
impl PhaseCoordinator for ConditionVariableLine {
    /// 获取流水线总阶段数
    fn total_phases(&self) -> usize {
        self.total_phases
    }

    /// 获取当前进度(已完成阶段数)
    fn current_phase(&self) -> usize {
        self.state.lock().unwrap().phase()
    }

    /// 等待指定阶段可开工(条件不满足则挂起等待,被唤醒后自动重检查)
    fn wait_until_ready(&self, phase: usize) {
        let guard = self.state.lock().unwrap();
        // 持锁检查条件;不满足则挂起并自动释放锁,notify 唤醒后自动重检查
        // (wait_while 返回持锁的 guard,条件满足时结束等待)
        let _guard = self
            .condvar
            .wait_while(guard, |s| !s.is_phase_ready(phase))
            .unwrap();
        // 立即释放条件变量返回的锁,避免后续日志二次加锁造成死锁(Mutex 非重入)
        drop(_guard);
        // 先取出珠宝名(临时 guard 立即释放),避免 format! 求值期间二次加锁死锁
        let jewelry_name = self.state.lock().unwrap().jewelry_name.clone();
        // 条件已满足,工位获准开工
        self.logger().debug(&format!(
            "条件变量:{} 第 {} 阶段(进度 {}/{})条件已满足,工位获准开工",
            jewelry_name,
            phase,
            self.current_phase(),
            self.total_phases
        ));
    }

    /// 标记当前工位已完成,推进共享进度并通知所有等待线程
    fn mark_complete(&self) {
        {
            let mut guard = self.state.lock().unwrap();
            guard.advance();
            self.logger().debug(&format!(
                "条件变量:{} 推进进度至 {}/{},准备通知等待线程",
                guard.jewelry_name, guard.current_phase, self.total_phases
            ));
        }
        // 释放锁后通知全部等待线程(唤醒后由 wait_while 自动重检查条件)
        self.condvar.notify_all();
    }

    /// 获取统一日志对象
    fn logger(&self) -> Arc<dyn Logger> {
        self.logger.clone()
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : process_service.rs
//! 业务流程应用服务(调度器)
//!
//! 职责:
//! - 持有工位注册表(12 个业务部门工位)与协调器工厂(构造器注入)
//! - 顺序调度:按供应链顺序逐个工位经条件变量同步执行(上下游严格衔接)
//! - 并发调度:多线程高并发,12 个工位线程通过条件变量(Mutex + Condvar)
//!   实现流水线同步(等待上游 → 执行 → 通知下游)
//! - 调用仓储保存执行记录;提供统计、记录、工位清单能力
//!
//! 每次调度创建一个全新的条件变量生产线(`ConditionVariableLine`),保证
//! 共享进度从零开始,从而真实演示条件变量的等待/通知机制。

use std::sync::Arc;

use crate::application::condition::condition_line::ConditionVariableLine;
use crate::common::error::ProcessError;
use crate::common::logging::Logger;
use crate::common::resilience::retry_circuit_breaker::RetryCircuitBreaker;
use crate::domain::condition::coordinator::PhaseCoordinator;
use crate::domain::condition::worker::StageWorker;
use crate::domain::dtos::process_dtos::{ProcessRequestDto, ProcessResponseDto};
use crate::domain::entities::jewelry::ProcessOutcome;
use crate::domain::repository::process_repository::{ProcessRecord, ProcessRepository};

/// 业务流程应用服务(条件变量模式调度器)
pub struct ProcessService {
    /// 工位注册表(12 个业务部门工位)
    workers: Vec<Arc<dyn StageWorker>>,
    /// 重试 + 熔断适配器(保护工位作业执行)
    resilience: Arc<RetryCircuitBreaker>,
    /// 流程仓储(依赖注入)
    repository: Arc<dyn ProcessRepository>,
    /// 统一日志(依赖注入)
    logger: Arc<dyn Logger>,
}

impl ProcessService {
    /// 创建业务流程应用服务
    ///
    /// # 参数
    /// - `workers`:工位注册表(按供应链顺序)
    /// - `resilience`:重试 + 熔断适配器
    /// - `repository`:流程仓储
    /// - `logger`:统一日志
    ///
    /// # 返回
    /// 应用服务实例
    pub fn new(
        workers: Vec<Arc<dyn StageWorker>>,
        resilience: Arc<RetryCircuitBreaker>,
        repository: Arc<dyn ProcessRepository>,
        logger: Arc<dyn Logger>,
    ) -> Self {
        Self {
            workers,
            resilience,
            repository,
            logger,
        }
    }

    /// 顺序调度:按供应链顺序逐个工位经条件变量同步执行,保存执行记录。
    ///
    /// # 参数
    /// - `request`:执行请求 DTO
    ///
    /// # 返回
    /// 各工位执行响应集合
    pub fn run_sequential(&self, request: ProcessRequestDto) -> Vec<ProcessResponseDto> {
        self.logger
            .info("========== 条件变量顺序调度:按供应链逐个工位经条件变量同步执行 ==========");
        // 每次调度创建全新的条件变量生产线(共享进度从零开始)
        let line = Arc::new(ConditionVariableLine::new(
            self.workers.len(),
            &request.jewelry.name,
            self.logger.clone(),
        ));
        let mut recorded = Vec::new();
        for worker in &self.workers {
            let line_clone = line.clone();
            let request_clone = request.clone();
            // 工位作业经「重试 + 熔断」保护(物流瞬时失败自动重试)
            let response = self
                .resilience
                .execute(|| worker.perform(line_clone.as_ref(), &request_clone))
                .unwrap_or_else(|err| {
                    ProcessResponseDto::new(
                        &format!("{}-{:06}", worker.stage_id(), crate::domain::entities::jewelry::next_sequence()),
                        worker.stage_name(),
                        false,
                        &err.to_string(),
                    )
                });
            self.logger.info(&format!(
                "  ✔ {} / {} 作业完成",
                worker.stage_id(),
                worker.stage_name()
            ));
            recorded.push(response);
        }
        self.logger.info(&format!(
            "条件变量流水线推进完毕:总进度 {}/{}",
            line.current_phase(),
            line.total_phases()
        ));
        self.save_responses(&recorded);
        recorded
    }

    /// 并发调度:对每个工位开独立线程,12 个线程通过条件变量实现流水线同步。
    ///
    /// # 参数
    /// - `request`:执行请求 DTO
    ///
    /// # 返回
    /// 各工位执行响应集合
    pub fn run_concurrent(&self, request: ProcessRequestDto) -> Vec<ProcessResponseDto> {
        self.logger
            .info("========== 条件变量并发调度:12 个工位线程经条件变量流水线同步 ==========");
        // 每次调度创建全新的条件变量生产线(共享进度从零开始)
        let line = Arc::new(ConditionVariableLine::new(
            self.workers.len(),
            &request.jewelry.name,
            self.logger.clone(),
        ));
        let mut handles = Vec::new();
        for worker in &self.workers {
            let worker_clone = worker.clone();
            let line_clone = line.clone();
            let request_clone = request.clone();
            let resilience_clone = self.resilience.clone();
            // 每个工位一个独立线程:等待上游条件 → 执行业务 → 通知下游
            handles.push(std::thread::spawn(move || {
                let result = resilience_clone
                    .execute(|| worker_clone.perform(line_clone.as_ref(), &request_clone));
                (worker_clone.stage_id().to_string(), result)
            }));
        }
        let mut recorded = Vec::new();
        for handle in handles {
            if let Ok((_, result)) = handle.join() {
                let response = result.unwrap_or_else(|err| {
                    ProcessResponseDto::new("", "并发作业", false, &err.to_string())
                });
                recorded.push(response);
            }
        }
        self.logger.info(&format!(
            "条件变量并发流水线推进完毕:总进度 {}/{}",
            line.current_phase(),
            line.total_phases()
        ));
        self.save_responses(&recorded);
        recorded
    }

    /// 执行指定单个工位作业(供端口契约使用;创建独立条件变量生产线)
    ///
    /// # 参数
    /// - `stage_id`:工位标识(如 PROCUREMENT / TRAINING)
    /// - `request`:执行请求 DTO
    ///
    /// # 返回
    /// - `Ok(ProcessResponseDto)`:工位执行响应
    /// - `Err(ProcessError)`:未知工位
    pub fn dispatch(
        &self,
        stage_id: &str,
        request: ProcessRequestDto,
    ) -> Result<ProcessResponseDto, ProcessError> {
        let worker = self
            .workers
            .iter()
            .find(|w| w.stage_id() == stage_id)
            .cloned()
            .ok_or_else(|| ProcessError::new("NOT_FOUND", &format!("未知工位:{}", stage_id)))?;
        let line = Arc::new(ConditionVariableLine::new(
            worker.stage_index() + 1,
            &request.jewelry.name,
            self.logger.clone(),
        ));
        // 单独派发单个工位:预置进度到该工位阶段(视为上游全部完成),
        // 使其在条件变量上立即获准开工(否则该工位会永远等待上游)
        line.advance_to(worker.stage_index());
        let line_clone = line.clone();
        let request_clone = request.clone();
        let response = self
            .resilience
            .execute(|| worker.perform(line_clone.as_ref(), &request_clone))
            .unwrap_or_else(|err| {
                ProcessResponseDto::new(
                    &format!(
                        "{}-{:06}",
                        worker.stage_id(),
                        crate::domain::entities::jewelry::next_sequence()
                    ),
                    worker.stage_name(),
                    false,
                    &err.to_string(),
                )
            });
        self.save_responses(&[response.clone()]);
        Ok(response)
    }

    /// 保存一批执行记录(内部辅助)
    ///
    /// # 参数
    /// - `responses`:执行响应集合
    fn save_responses(&self, responses: &[ProcessResponseDto]) {
        for resp in responses {
            let outcome = if resp.success {
                ProcessOutcome::success(&resp.instance_id, &resp.message)
            } else {
                ProcessOutcome::failure(&resp.instance_id, &resp.message)
            };
            let record = ProcessRecord {
                instance_id: resp.instance_id.clone(),
                process_name: resp.process_name.clone(),
                outcome,
                executed_at: chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string(),
            };
            if let Err(err) = self.repository.save(record) {
                self.logger.error(&format!("保存业务执行记录失败:{}", err));
            }
        }
    }

    /// 获取全部已注册工位清单
    ///
    /// # 返回
    /// 全部工位实例
    pub fn workers(&self) -> Vec<Arc<dyn StageWorker>> {
        self.workers.clone()
    }

    /// 获取业务执行统计(成功数量,失败数量)
    ///
    /// # 返回
    /// `(成功数量, 失败数量)` 元组
    pub fn statistics(&self) -> (usize, usize) {
        self.repository.count()
    }

    /// 获取全部业务执行记录(用于追溯/汇总展示)
    ///
    /// # 返回
    /// 全部执行记录
    pub fn records(&self) -> Vec<ProcessRecord> {
        self.repository.find_all()
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : retry_circuit_breaker.rs
//! 重试 + 熔断适配器(Resilience Adapter)
//!
//! 作用:在中介者协调同事执行依赖外部系统(如质检系统、物流接口、财务网关)时,
//! 提供「自动重试 + 熔断保护」:
//! - **重试**:瞬时失败时按指数退避重试,直至达到最大重试次数。
//! - **熔断**:连续失败达到阈值后打开熔断器,快速失败(不再重试),
//!   经冷却时间后进入半开状态,试探恢复。
//!
//! 线程安全:内部状态使用 `Mutex` 保护,可被 `Arc` 共享到多个线程高并发使用。

use std::sync::Mutex;
use std::time::{Duration, Instant};

use crate::common::error::ProcessError;

/// 熔断器打开错误码
const ERROR_CIRCUIT_OPEN: &str = "CIRCUIT_OPEN";

/// 熔断器状态
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CircuitState {
    /// 关闭(正常运行,允许调用)
    Closed,
    /// 打开(熔断,快速失败)
    Open,
    /// 半开(冷却结束,试探性放行一次)
    HalfOpen,
}

/// 熔断器内部状态(受互斥锁保护)
struct CircuitInner {
    /// 当前熔断状态
    state: CircuitState,
    /// 连续失败次数
    consecutive_failures: u32,
    /// 熔断打开时刻(用于计算冷却时间)
    opened_at: Option<Instant>,
}

/// 重试 + 熔断适配器(线程安全、可共享)
pub struct RetryCircuitBreaker {
    /// 最大重试次数(成功之前最多额外尝试的次数)
    max_retries: u32,
    /// 熔断失败阈值(连续失败达到该次数即打开熔断器)
    failure_threshold: u32,
    /// 熔断冷却时间(打开后等待该时长才允许半开试探)
    cooldown: Duration,
    /// 内部熔断状态
    inner: Mutex<CircuitInner>,
}

impl RetryCircuitBreaker {
    /// 创建重试 + 熔断适配器
    ///
    /// # 参数
    /// - `max_retries`:最大重试次数
    /// - `failure_threshold`:熔断失败阈值
    /// - `cooldown`:熔断冷却时长
    ///
    /// # 返回
    /// 适配器实例
    pub fn new(max_retries: u32, failure_threshold: u32, cooldown: Duration) -> Self {
        Self {
            max_retries,
            failure_threshold,
            cooldown,
            inner: Mutex::new(CircuitInner {
                state: CircuitState::Closed,
                consecutive_failures: 0,
                opened_at: None,
            }),
        }
    }

    /// 获取当前熔断状态(用于日志输出)
    ///
    /// # 返回
    /// 当前 `CircuitState`
    #[allow(dead_code)]
    pub fn state(&self) -> CircuitState {
        self.inner
            .lock()
            .map(|g| g.state)
            .unwrap_or(CircuitState::Closed)
    }

    /// 执行受保护的操作:带「重试 + 熔断」
    ///
    /// # 泛型参数
    /// - `F`:操作闭包类型
    /// - `O`:成功返回值类型
    ///
    /// # 参数
    /// - `operation`:返回 `Result<O, ProcessError>` 的操作闭包
    ///
    /// # 返回
    /// - `Ok(O)`:操作最终成功
    /// - `Err(ProcessError)`:重试耗尽或熔断快速失败
    pub fn execute<F, O>(&self, operation: F) -> Result<O, ProcessError>
    where
        F: Fn() -> Result<O, ProcessError>,
    {
        // 步骤一:熔断前置检查(快速失败)
        {
            let mut guard = self.inner.lock().unwrap();
            if guard.state == CircuitState::Open {
                if let Some(opened_at) = guard.opened_at {
                    // 冷却时间未过 → 直接快速失败
                    if opened_at.elapsed() < self.cooldown {
                        return Err(ProcessError::new(
                            ERROR_CIRCUIT_OPEN,
                            "熔断器已打开,请求快速失败,请稍后重试",
                        ));
                    }
                }
                // 冷却时间已过 → 转为半开状态,允许一次试探
                guard.state = CircuitState::HalfOpen;
            }
        }

        // 步骤二:带重试地执行操作
        let mut attempt = 0u32;
        loop {
            match operation() {
                Ok(value) => {
                    // 成功:重置失败计数,恢复关闭状态
                    let mut guard = self.inner.lock().unwrap();
                    guard.consecutive_failures = 0;
                    guard.state = CircuitState::Closed;
                    guard.opened_at = None;
                    return Ok(value);
                }
                Err(err) => {
                    attempt += 1;
                    {
                        let mut guard = self.inner.lock().unwrap();
                        guard.consecutive_failures += 1;
                        // 连续失败达到阈值 → 打开熔断器
                        if guard.consecutive_failures >= self.failure_threshold {
                            guard.state = CircuitState::Open;
                            guard.opened_at = Some(Instant::now());
                            return Err(err);
                        }
                    }
                    // 未熔断但重试次数已耗尽 → 返回错误
                    if attempt > self.max_retries {
                        return Err(err);
                    }
                    // 指数退避等待后重试
                    std::thread::sleep(Duration::from_millis(100 * attempt as u64));
                }
            }
        }
    }
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : error.rs
//! 统一错误类型定义
//!
//! 全项目统一使用 `ProcessError` 作为业务错误载体,携带错误码与消息,
//! 便于上层(应用层/接口层/表现层)统一捕获与日志输出。

/// 业务流程错误(统一错误载体)
#[derive(Debug, Clone)]
pub struct ProcessError {
    /// 错误码(如 EXECUTION_FAILED / CIRCUIT_OPEN 等)
    pub code: String,
    /// 错误消息(中文,可直接输出到日志与界面)
    pub message: String,
}

impl ProcessError {
    /// 创建业务流程错误
    ///
    /// # 参数
    /// - `code`:错误码
    /// - `message`:错误消息
    ///
    /// # 返回
    /// 构造好的 `ProcessError` 实例
    pub fn new(code: &str, message: &str) -> Self {
        Self {
            code: code.to_string(),
            message: message.to_string(),
        }
    }
}

/// 格式化输出(支持 `{}` 直接打印)
impl std::fmt::Display for ProcessError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "[{}] {}", self.code, self.message)
    }
}

/// 实现标准 Error trait,可向上转换为 `Box<dyn Error>`
impl std::error::Error for ProcessError {}

/// 预留的标准错误码字典(供上层业务模块调用,作为统一错误码契约预留给扩展)
#[allow(dead_code)]
pub mod error_code {
    /// 前置校验失败
    pub const VALIDATE_FAILED: &str = "VALIDATE_FAILED";
    /// 业务执行失败
    pub const EXECUTION_FAILED: &str = "EXECUTION_FAILED";
    /// 熔断器打开(快速失败)
    pub const CIRCUIT_OPEN: &str = "CIRCUIT_OPEN";
    /// 资源未找到
    pub const NOT_FOUND: &str = "NOT_FOUND";
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : logging.rs
//! 统一日志抽象接口(对应 C# 中的 `ILogger<T>`)
//!
//! 所有组件(调度器、中介者、同事、入口)仅依赖该接口输出日志,
//! 具体实现(文件日志)由基础设施层通过 DI 注入。
//! 保证控制台输出与日志文件输出格式完全一致。
//!
//! 日志文件规约:
//! ```text
//! Logs/
//!   2026-07-06/
//!     app-info.log
//!     app-error.log
//!     app-debug.log
//!     app-warn.log
//! ```

/// 日志等级
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LogLevel {
    /// 调试(用于输出详细执行过程)
    Debug,
    /// 信息(用于输出常规流程状态)
    Info,
    /// 警告(用于输出可恢复异常)
    Warn,
    /// 错误(用于输出失败/异常)
    Error,
}

impl LogLevel {
    /// 获取日志等级标签(用于日志前缀,控制台与文件一致)
    ///
    /// # 返回
    /// 等级标签字符串
    pub fn tag(&self) -> &'static str {
        match self {
            LogLevel::Debug => "DEBUG",
            LogLevel::Info => "INFO",
            LogLevel::Warn => "WARN",
            LogLevel::Error => "ERROR",
        }
    }

    /// 获取日志等级对应的文件名(按等级分文件)
    ///
    /// # 返回
    /// 文件名(如 `app-info.log`)
    pub fn file_name(&self) -> &'static str {
        match self {
            LogLevel::Debug => "app-debug.log",
            LogLevel::Info => "app-info.log",
            LogLevel::Warn => "app-warn.log",
            LogLevel::Error => "app-error.log",
        }
    }
}

/// 统一日志接口(线程安全、可对象化注入使用)
///
/// 设计要点:
/// - `Send + Sync` 保证可在多线程/高并发环境下共享(`Arc<dyn Logger>`)
/// - 方法非泛型,保持对象安全(object-safe),可向上转型为 trait 对象注入
pub trait Logger: Send + Sync {
    /// 输出调试日志
    ///
    /// # 参数
    /// - `message`:日志消息
    fn debug(&self, message: &str);

    /// 输出信息日志
    ///
    /// # 参数
    /// - `message`:日志消息
    fn info(&self, message: &str);

    /// 输出警告日志
    ///
    /// # 参数
    /// - `message`:日志消息
    fn warn(&self, message: &str);

    /// 输出错误日志
    ///
    /// # 参数
    /// - `message`:日志消息
    fn error(&self, message: &str);
}
//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : result.rs
//! 统一结果返回类型
//!
//! 用于表现层/接口层向调用方返回统一结构的操作结果,保证输出格式一致。

/// 通用操作结果(泛型,表现层返回载体)
///
/// 预留给需要结构化返回(成功/失败 + 业务数据)的调用方使用;
/// 当前控制台演示直接输出日志,未构造该结果,属预留 API。
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct ApiResult<T> {
    /// 是否成功
    pub success: bool,
    /// 结果消息
    pub message: String,
    /// 业务数据(可选)
    pub data: Option<T>,
}

impl<T> ApiResult<T> {
    /// 创建成功结果
    ///
    /// # 参数
    /// - `data`:业务数据
    ///
    /// # 返回
    /// 成功结果
    #[allow(dead_code)]
    pub fn ok(data: T) -> Self {
        Self {
            success: true,
            message: "操作成功".to_string(),
            data: Some(data),
        }
    }

    /// 创建失败结果
    ///
    /// # 参数
    /// - `message`:失败消息
    ///
    /// # 返回
    /// 失败结果
    #[allow(dead_code)]
    pub fn err(message: &str) -> Self {
        Self {
            success: false,
            message: message.to_string(),
            data: None,
        }
    }
}

调用:
 

//!# encoding: utf-8 
//!# 版权所有  2026 ©涂聚文有限公司™ ®
//!# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
//!# 描述:Condition Variable  Pattern 条件变量模式  Synchronization Patterns 同步型模式
//!# Author    : geovindu,Geovin Du 涂聚文.
//!# IDE       : RustRover  2025.1.1 Rust  rustc 1.98.1 
//!# os        : windows 10
//!# database  : mysql 9.0 sql server 2025, postgreSQL 18.0  Oracle 21c Neo4j
//!# Datetime  : 2026/10/27 21:27 
//!# User      :  geovindu
//!# Product   : RustRover
//!# Project   : ConditionVariablePattern
//!# File      : main.rs
//! 条件变量模式(Condition Variable Pattern,同步型并发模式)— 珠宝行业全程业务
//!
//! 业务范围:原料采购核验、设计制图、加工生产、质检、包装、物流、财务、
//!           营销推广、业务销售、人事行政、IT、培训。
//!
//! 条件变量模式核心思想:
//! - 多个线程在共享的「条件」上等待(`Condvar::wait`),直到某个条件成立;
//!   条件改变方通过 `notify_all`/`notify_one` 唤醒等待线程。
//! - 珠宝生产流水线:12 个业务部门作为 12 个工位(工作线程),每个工位在
//!   条件变量上等待「上游阶段已就绪」的条件,完成本工位业务后推进进度并
//!   通知下游工位,形成严格的上下游同步(同步型并发模式)。
//! - Rust 标准实现:`Mutex<ProductionState>` + `Condvar`,使用 `wait_while`
//!   自动「等待→唤醒→重检查」,避免虚假唤醒(spurious wakeup)。
//!
//! 工程化特性:
//! - 日志按日期分文件夹、按日志等级分文件(Logs/2026-07-06/app-*.log)
//! - 注入统一日志对象 `Arc<dyn Logger>`(对应 C# 的 `ILogger<T>`)
//! - DTO 业务传输对象、适配器「重试 + 熔断」
//! - 兼容依赖注入(DI)、线程安全、高并发写入
//! - 调度器 / 工位 / 协调器 / 入口全部使用统一标准日志,控制台与文件输出完全一致
//!
//! DDD 严格分层(依赖方向:presentation → interface → application → domain → common;
//! infrastructure 实现 domain/interface 定义的接口):
//! - domain          领域层(实体、DTO、条件变量抽象、仓储接口)
//! - common          通用层(错误、结果、日志接口、重试熔断)
//! - application     应用层(条件变量生产线、12 个部门工位、应用服务调度器)
//! - infrastructure  基础设施层(文件日志、DI 容器、内存仓储)
//! - interface       接口层(对外端口契约、业务信封契约)
//! - presentation    表现层(控制台入口 / 组合根装配 / 端口实现)

// 声明顶层模块(对应六个文件夹)
mod application;
mod common;
mod domain;
mod infrastructure;
mod interface;
mod presentation;

use std::sync::Arc;

use infrastructure::di::container::ServiceContainer;
use presentation::console::controller::ApplicationController;

/// 程序入口(组合根:装配依赖注入容器 → 创建应用控制器 → 启动条件变量演示)
fn main() {
    // 1. 构建依赖注入容器(组合根,统一装配工位、协调器与全部服务)
    let container = Arc::new(ServiceContainer::new());

    // 2. 创建应用控制器(表现层,实现 interface 定义的对外端口契约)
    let controller = ApplicationController::new(container);

    // 3. 启动珠宝行业全程业务流程(条件变量模式)演示
    controller.run();
}

输出:

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值