go: N-Barrier Pattern

项目结构:

安装:

Go 复制代码
go get -u go.uber.org/zap
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/5/26 22:06
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : config.go
*/
package config
 
import "time"
 
// AppConfig 全局生产配置
type AppConfig struct {
    // 生产阶段
    ProductionSteps   int
    ProductionTimeout time.Duration
 
    // 入库阶段
    WarehouseSteps   int
    WarehouseTimeout time.Duration
 
    // 发货阶段
    DeliverySteps   int
    DeliveryTimeout time.Duration
 
    // 重试
    MaxRetryCount int
    RetryInterval time.Duration
}
 
func Load() *AppConfig {
    return &AppConfig{
        ProductionSteps:   5,
        ProductionTimeout: 10 * time.Second,
 
        WarehouseSteps:   5,
        WarehouseTimeout: 5 * time.Second,
 
        DeliverySteps:   1,
        DeliveryTimeout: 3 * time.Second,
 
        MaxRetryCount: 2,
        RetryInterval: 500 * time.Millisecond,
    }
}
 
 
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/5/26 22:07
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : logger.go
*/
package logger
 
import (
    "go.uber.org/zap"
    "go.uber.org/zap/zapcore"
)
 
var log *zap.Logger
 
func Init() {
    config := zap.NewProductionConfig()
    config.EncoderConfig.TimeKey = "time"
    config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
    config.DisableCaller = true
 
    l, _ := config.Build()
    log = l
}
 
func Info(msg string, fields ...zap.Field) {
    log.Info(msg, fields...)
}
 
func Error(msg string, fields ...zap.Field) {
    log.Error(msg, fields...)
}
 
func Debug(msg string, fields ...zap.Field) {
    log.Debug(msg, fields...)
}
 
func With(fields ...zap.Field) *zap.Logger {
    return log.With(fields...)
}
 
func Sync() {
    _ = log.Sync()
}
  
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/5/26 22:06
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : barrier.go
*/
package barrier
 
import "sync"
 
// StageBarrier 多阶段屏障
type StageBarrier struct {
    wg    *sync.WaitGroup
    stage string
}
 
func NewStageBarrier(n int, stage string) *StageBarrier {
    wg := &sync.WaitGroup{}
    wg.Add(n)
    return &StageBarrier{wg: wg, stage: stage}
}
 
func (s *StageBarrier) Done() {
    s.wg.Done()
}
 
func (s *StageBarrier) Wait() {
    s.wg.Wait()
}
 
func (s *StageBarrier) Stage() string {
    return s.stage
}
 
 
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/5/26 22:08
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : model.go
*/
package model
 
import "time"
 
// Step 珠宝生产步骤
type Step string
 
const (
    StepPurchase  = Step("原料采购")
    StepDesign    = Step("款式设计")
    StepProcess   = Step("工艺加工")
    StepQuality   = Step("品质质检")
    StepPackaging = Step("成品包装")
)
 
// WarehouseStep 入库步骤
type WarehouseStep string
 
const (
    WarehouseCheck   = WarehouseStep("入库核验")
    WarehouseLabel   = WarehouseStep("贴标入仓")
    WarehouseStock   = WarehouseStep("库存更新")
    WarehousePhoto   = WarehouseStep("成品拍照")
    WarehouseArchive = WarehouseStep("档案归档")
)
 
// DeliveryStep 发货步骤
type DeliveryStep string
 
const (
    DeliveryShip = DeliveryStep("批量发货")
)
 
// TaskResult 任务执行结果
type TaskResult struct {
    Stage   string
    Step    string
    Cost    time.Duration
    Success bool
    Retry   int
    Error   error
}
 
// GetProductionSteps 获取生产步骤
func GetProductionSteps() []Step {
    return []Step{StepPurchase, StepDesign, StepProcess, StepQuality, StepPackaging}
}
 
// GetWarehouseSteps 获取入库步骤
func GetWarehouseSteps() []WarehouseStep {
    return []WarehouseStep{WarehouseCheck, WarehouseLabel, WarehouseStock, WarehousePhoto, WarehouseArchive}
}
 
// GetDeliverySteps 获取发货步骤
func GetDeliverySteps() []DeliveryStep {
    return []DeliveryStep{DeliveryShip}
}
 
// GetStepDuration 步骤耗时
func GetStepDuration(anyStep any) time.Duration {
    switch s := anyStep.(type) {
    case Step:
        switch s {
        case StepPurchase:
            return 2 * time.Second
        case StepDesign:
            return 3 * time.Second
        case StepProcess:
            return 4 * time.Second
        case StepQuality:
            return 2 * time.Second
        case StepPackaging:
            return 1 * time.Second
        }
    case WarehouseStep:
        return 1 * time.Second
    case DeliveryStep:
        return 2 * time.Second
    }
    return 1 * time.Second
}
 
 
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/5/26 22:09
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : collector.go
*/
package result
 
import (
    "godesginpattern/nbarrier/jewelry/model"
    "sync"
)
 
type Collector struct {
    mu      sync.Mutex
    results []model.TaskResult
}
 
func NewCollector() *Collector {
    return &Collector{}
}
 
func (c *Collector) Add(res model.TaskResult) {
    c.mu.Lock()
    defer c.mu.Unlock()
    c.results = append(c.results, res)
}
 
func (c *Collector) All() []model.TaskResult {
    c.mu.Lock()
    defer c.mu.Unlock()
    return c.results
}
 
func (c *Collector) SuccessCount() int {
    c.mu.Lock()
    defer c.mu.Unlock()
    count := 0
    for _, r := range c.results {
        if r.Success {
            count++
        }
    }
    return count
}
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/5/26 22:09
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : worker.go
*/
package worker
 
import (
    "context"
    "go.uber.org/zap"
    "godesginpattern/nbarrier/barrier"
    "godesginpattern/nbarrier/common/logger"
    "godesginpattern/nbarrier/jewelry/model"
    "godesginpattern/nbarrier/result"
    "time"
)
 
type Task interface {
    Run(ctx context.Context) (model.TaskResult, error)
}
 
func RunWithRetryAndTimeout(
    ctx context.Context,
    task Task,
    b *barrier.StageBarrier,
    collector *result.Collector,
    maxRetry int,
    retryInterval time.Duration,
) {
    go func() {
        defer b.Done()
 
        stepLog := logger.With(zap.String("stage", b.Stage()))
        var res model.TaskResult
 
        for retry := 0; retry <= maxRetry; retry++ {
            select {
            case <-ctx.Done():
                stepLog.Error("任务超时取消", zap.Int("retry", retry))
                return
            default:
            }
 
            result, err := task.Run(ctx)
            result.Retry = retry
            result.Stage = b.Stage()
 
            if err == nil {
                res = result
                stepLog.Info("步骤完成",
                    zap.String("step", result.Step),
                    zap.Duration("cost", result.Cost),
                    zap.Int("retry", retry))
                break
            }
 
            stepLog.Error("步骤执行失败",
                zap.String("step", result.Step),
                zap.Int("retry", retry),
                zap.Error(err))
 
            if retry == maxRetry {
                res = result
                break
            }
 
            time.Sleep(retryInterval)
        }
 
        collector.Add(res)
    }()
}
Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/5/26 22:11
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : service.go
*/
package service
 
import (
    "context"
    "go.uber.org/zap"
    "godesginpattern/nbarrier/common/logger"
    "godesginpattern/nbarrier/jewelry/model"
    "time"
)
 
type JewelryService struct{}
 
func NewJewelryService() *JewelryService {
    return &JewelryService{}
}
 
// ---------------- 生产任务 ----------------
type ProductionTask struct {
    Step model.Step
}
 
func (t *ProductionTask) Run(ctx context.Context) (model.TaskResult, error) {
    start := time.Now()
    dur := model.GetStepDuration(t.Step)
 
    logger.Info("开始生产步骤", zap.String("step", string(t.Step)))
    time.Sleep(dur)
 
    return model.TaskResult{
        Step:    string(t.Step),
        Cost:    time.Since(start),
        Success: true,
    }, nil
}
 
// ---------------- 入库任务 ----------------
type WarehouseTask struct {
    Step model.WarehouseStep
}
 
func (t *WarehouseTask) Run(ctx context.Context) (model.TaskResult, error) {
    start := time.Now()
    dur := model.GetStepDuration(t.Step)
 
    logger.Info("开始入库步骤", zap.String("step", string(t.Step)))
    time.Sleep(dur)
 
    return model.TaskResult{
        Step:    string(t.Step),
        Cost:    time.Since(start),
        Success: true,
    }, nil
}
 
// ---------------- 发货任务 ----------------
type DeliveryTask struct {
    Step model.DeliveryStep
}
 
func (t *DeliveryTask) Run(ctx context.Context) (model.TaskResult, error) {
    start := time.Now()
    dur := model.GetStepDuration(t.Step)
 
    logger.Info("开始发货步骤", zap.String("step", string(t.Step)))
    time.Sleep(dur)
 
    return model.TaskResult{
        Step:    string(t.Step),
        Cost:    time.Since(start),
        Success: true,
    }, nil
}
  

调用:

Go 复制代码
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:N-Barrier Pattern 屏障模式  go get -u go.uber.org/zap
#
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/5/26 22:30
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : nbarrierbll.go
 
barrier/
├── go.mod
├── go.sum
├── main.go    # 入口:依赖注入+启动
├── config/
│   └── config.go             # 全局配置
├──
│   ├── barrier/              # 多阶段屏障核心
│   │   └── barrier.go
│   ├── jewelry/              # 珠宝业务域
│   │   ├── model/            # 模型+枚举
│   │   └── service/          # 业务逻辑
│   ├── pkg/                  # 内部公共包
│   │   ├── logger/           # zap日志
│   │   └── worker/           # 并发+重试+超时
│   └── result/               # 结果收集器
└── scripts/                  # 部署脚本(预留)
*/
package bll
 
import (
    "context"
    "go.uber.org/zap"
    "godesginpattern/nbarrier/barrier"
    "godesginpattern/nbarrier/common/logger"
    "godesginpattern/nbarrier/common/worker"
    "godesginpattern/nbarrier/config"
    "godesginpattern/nbarrier/jewelry/model"
    "godesginpattern/nbarrier/jewelry/service"
    "godesginpattern/nbarrier/result"
    "os/signal"
    "syscall"
    "time"
)
 
func NbarrierMain() {
    // 初始化日志
    logger.Init()
    defer logger.Sync()
 
    // 加载配置
    cfg := config.Load()
 
    // 优雅关闭
    ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
    defer stop()
 
    logger.Info("=== 珠宝全流程生产系统启动 ===")
    logger.Info("配置加载完成",
        zap.Int("生产步骤", cfg.ProductionSteps),
        zap.Int("入库步骤", cfg.WarehouseSteps),
        zap.Int("重试次数", cfg.MaxRetryCount))
 
    // 结果收集器
    collector := result.NewCollector()
 
    // ==========================================
    // 阶段1:生产屏障
    // ==========================================
    prodCtx, cancel1 := context.WithTimeout(ctx, cfg.ProductionTimeout)
    defer cancel1()
 
    prodBarrier := barrier.NewStageBarrier(cfg.ProductionSteps, "生产")
    steps := model.GetProductionSteps()
 
    for _, step := range steps {
        task := &service.ProductionTask{Step: step}
        worker.RunWithRetryAndTimeout(
            prodCtx, task, prodBarrier, collector,
            cfg.MaxRetryCount, cfg.RetryInterval)
    }
 
    logger.Info("=== 等待所有生产步骤完成 ===")
    prodBarrier.Wait()
    logger.Info("=== 【生产屏障通过】 ===")
 
    // ==========================================
    // 阶段2:入库屏障
    // ==========================================
    whCtx, cancel2 := context.WithTimeout(ctx, cfg.WarehouseTimeout)
    defer cancel2()
 
    whBarrier := barrier.NewStageBarrier(cfg.WarehouseSteps, "入库")
    whSteps := model.GetWarehouseSteps()
 
    for _, step := range whSteps {
        task := &service.WarehouseTask{Step: step}
        worker.RunWithRetryAndTimeout(
            whCtx, task, whBarrier, collector,
            cfg.MaxRetryCount, cfg.RetryInterval)
    }
 
    logger.Info("=== 等待所有入库步骤完成 ===")
    whBarrier.Wait()
    logger.Info("=== 【入库屏障通过】 ===")
 
    // ==========================================
    // 阶段3:发货屏障
    // ==========================================
    deliverCtx, cancel3 := context.WithTimeout(ctx, cfg.DeliveryTimeout)
    defer cancel3()
 
    dlBarrier := barrier.NewStageBarrier(cfg.DeliverySteps, "发货")
    dlSteps := model.GetDeliverySteps()
 
    for _, step := range dlSteps {
        task := &service.DeliveryTask{Step: step}
        worker.RunWithRetryAndTimeout(
            deliverCtx, task, dlBarrier, collector,
            cfg.MaxRetryCount, cfg.RetryInterval)
    }
 
    logger.Info("=== 等待发货完成 ===")
    dlBarrier.Wait()
    logger.Info("=== 【发货屏障通过】 ===")
 
    // ==========================================
    // 最终汇总
    // ==========================================
    time.Sleep(300 * time.Millisecond)
    logger.Info("========================================")
    logger.Info("✅ 全流程完成",
        zap.Int("总任务数", len(collector.All())),
        zap.Int("成功数", collector.SuccessCount()))
    logger.Info("✅ 珠宝成品 → 生产 → 入库 → 发货 全流程完成")
    logger.Info("========================================")
}

输出:

相关推荐
三品吉他手会点灯17 小时前
C语言学习笔记 - 50.流程控制4 - 流程控制为什么非常非常重要
c语言·开发语言·笔记·学习
Oneslide18 小时前
Ubuntu 26.04 完整安装 Fcitx5 中文拼音输入法指南(适配默认Wayland)
后端
huangdong_19 小时前
电商平台图片URL原图转换技术深度解析:从缩略图到高清原图的完整方案
java·后端·spring
記億揺晃着的那天19 小时前
Java 调用外部 Go 程序的实践:ProcessBuilder 在生产环境中的应用
java·golang·processbuilder
掘金码甲哥19 小时前
3min手搓一个帮助文档站,很合理吧!
后端
一只旭宝19 小时前
【C++入门精讲22】常见设计模式
c++·设计模式
在放️20 小时前
Python 爬虫 · 第三方代理接入与合规使用
开发语言·爬虫·python
KANGBboy20 小时前
java知识五(继承)
java·开发语言
c++之路20 小时前
Bazel C++ 构建系列文档(三):构建第一个 C++ 项目
开发语言·c++
AI人工智能+电脑小能手20 小时前
【大白话说Java面试题 第117题】【并发篇】第17题:线程有几种状态,之间如何转换?
java·开发语言·面试