项目结构:

//!# 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();
}
输出:

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

425

被折叠的 条评论
为什么被折叠?



