modular

module
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 29, 2026 License: MIT

README

modular

modular 是一套 Go 基础设施模块化积木库(module path: github.com/wplbyx/modular,Go 1.26+)。它不是业务框架,也不接管业务代码;它提供可复用的基础设施组件、生命周期编排、配置加载、服务注册发现、传输层适配和常用工程模式,让业务项目通过依赖注入把应用组装起来。

核心目标:

  • Application 只负责编排生命周期,不处理业务逻辑。
  • core.Endpoint 表示接收流量或事件的入口,例如 HTTP、gRPC、SSE、消息订阅。
  • core.Resource 表示支撑性基础设施,例如 DB、Redis、Storage、Telemetry。
  • core.ServiceNode 表示服务实例身份,用于注册与发现;Endpoint.Name() / Resource.Name() 只作为日志标签。
  • 业务层应通过 proto 生成的接口解耦,单体和微服务切换只改 cmd 装配层。

核心模型

模型 职责
core.Resource packages/core 基础设施生命周期:Setup(ctx) / Close(ctx),不阻塞,不接流量。
core.Endpoint packages/core 服务入口生命周期:Startup(ctx) / Shutdown(ctx)Startup 必须阻塞到服务停止。
core.ServiceNode packages/core 一个 Application 对应一个服务节点,包含服务名、版本、实例 ID 和多个 transport。
registry.Registrar packages/registry ServiceNode 注册到 Consul 等注册中心。
registry.Discovery packages/registry 按服务名发现实例,或 watch 实例变化。
app.Application packages/app 统一管理 Resource、Endpoint、Registrar 和 ServiceNode 的启动与关闭顺序。

Application.Run 的顺序固定:

Resource.Setup()  FIFO
  -> Registrar.Register(ServiceNode)
  -> Endpoint.Startup()  并行阻塞
  -> Endpoint.Shutdown() 并行
  -> Registrar.Unregister(ServiceNode)
  -> Resource.Close()    LIFO

零 endpoint 的 Application 会打印 warning 并立即返回。接入 Application 的 endpoint 必须保证 Startup 在正常运行时阻塞,且 Shutdown 能解除阻塞。

模块总览

模块 内容
packages/core 零依赖核心抽象:ResourceEndpointTransportServiceNode
packages/app 应用生命周期编排器,提供 WithServiceNodeWithRegistrarWithResourceWithEndpoint
packages/config Viper 配置加载器与 Cobra 命令集成,支持本地文件、远程 KV、环境变量和自动模块 flags。
packages/config/configitem 可组合的强类型基础设施配置:Application、HTTP、GRPC、Database、Redis、Storage、Logging、Telemetry 和消息中间件。
packages/log Context 强制日志接口;Zap 输出与基于 cyub/ringbuffer 的异步分发,支持文件轮转、动态 OpenTelemetry sink 和有界降级。
packages/metadata 不可变、分 scope 的上下文元数据,统一 HTTP/gRPC/消息 Header 与 OTel trace context 穿透。
packages/eventbus 进程内有序 EventBus Resource;队列数据直接存放在 cyub/ringbuffer.MpscRingBuffer
packages/errs Kratos 风格统一错误、多语言 YAML Catalog、错误链/堆栈诊断与客户端/日志分流。
packages/generate 可安装的代码生成工具;err_template_generrs.Define 生成并校验多语言 YAML。
packages/util AES/RSA/ECC、随机字符串、URL、HTTP 请求和 context 工具。
packages/transport/server/http 基于 Gin 的 HTTP endpoint,支持中间件、健康检查、TLS、h2c;构造时即监听端口。
packages/transport/server/rpc gRPC endpoint,支持健康检查、拦截器和 mTLS。
packages/transport/server/sse SSE 服务,可挂载到 HTTP 路由,作为 core.Endpoint 管理连接生命周期。
packages/transport/client 显式注入的 HTTP / gRPC 客户端,默认接入 Metadata、OTel、访问日志和弹性保护。
packages/transport/pubsub 消息订阅 endpoint 抽象,以及 Kafka、MQTT、RocketMQ、Redis Pub/Sub、Redis Stream 适配。
packages/registry Consul 注册发现、K8s discovery、gRPC resolver;Consul 按 transport 注册服务记录。
packages/infra/database Bun / GORM / MongoDB 数据库连接能力;Bun、GORM 提供可直接注入 Application 的 Resource。
packages/infra/cache/redis go-redis 客户端、布隆过滤器、幂等工具。
packages/infra/storage 对象存储富接口与可选直传预签名接口,当前实现为本地磁盘 filedisk 和阿里云 OSS v2 alioss
packages/telemetry OpenTelemetry trace、metric、log provider,作为 core.Resource 注入应用。
packages/resilience 熔断、重试、限流、隔板,以及基于 Kratos Aegis BBR/SRE 的 Transport 自适应保护。
packages/patterns 缓存模式(Cache-Aside、Write-Through、Write-Behind、Refresh-Ahead)和并发模式。
packages/pool 可观测的有界异步任务池;支持满载立即拒绝或有界排队,并作为 Resource 管理。
packages/idgen 不透明业务 ID seam,以及 UUIDv7、可配置 Snowflake 和节点租约适配器。

典型使用方式

下游项目通常只在 cmd/<process>/main.go 里组装 modular 基础设施。业务代码放在 internal/,通过 proto 生成的接口暴露能力;切换 DB、Redis、Storage、HTTP/gRPC 或进程拓扑时,优先改 cmd 装配层。

异步任务池需要显式注入并交给 Application 管理:

workerPool, err := pool.New(pool.Config{
	Name:          "email-workers",
	Capacity:      32,
	Policy:        pool.Queue,
	QueueCapacity: 256,
}, logger)
application, err := app.NewApplication(ctx, &cfg.Application, logger,
	app.WithResource(workerPool),
)

业务代码通过 core.Provider[idgen.Generator] 使用不透明 ID。UUIDv7 不需要分布式协调,是单体和微服务的默认方案:

ids := idresource.NewUUIDv7("business-id")
application, err := app.NewApplication(ctx, &cfg.Application, logger,
	app.WithResource(ids),
)
repository := NewRepository(ids)

Snowflake 使用显式、不可变的位布局。单体可以用 snowflake.StaticNode(0);微服务必须注入能保证节点号唯一、续租失败即关闭 Lost() 的租约适配器。静态节点号本身不代表自动高可用。

配置入口推荐使用 config.NewRoot[T]。它会扫描业务聚合配置中实现 FlagProvider 的模块,注册 Cobra flags,并按以下优先级合并:

显式 Cobra 配置参数 > 环境变量 > 本地文件 > 远程 KV > FlagSpec 默认值

共享配置源参数:

--config, -c <path>   本地配置文件
--remote <url>        etcd://host/key 或 consul://host/key

本地与远程可以同时使用;远程读取失败时,只有已经成功读取的本地文件可以兜底。两者格式不一致时会记录 warning 并忽略远程配置。etcd:// 默认映射到 etcd v3,远程值没有扩展名时默认按 YAML 解析,可用 ?format=json 显式指定。

一个最小 HTTP 应用大致如下:

package main

import (
	"context"
	"fmt"
	"net/http"
	"os"
	"os/signal"
	"syscall"

	"github.com/gin-gonic/gin"

	"github.com/wplbyx/modular/packages/app"
	modularconfig "github.com/wplbyx/modular/packages/config"
	"github.com/wplbyx/modular/packages/core"
	"github.com/wplbyx/modular/packages/log"
	modulartransport "github.com/wplbyx/modular/packages/transport"
	httpserver "github.com/wplbyx/modular/packages/transport/server/http"

	projectconfig "<project>/config/user"
)

func main() {
	ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
	defer cancel()

	command := modularconfig.NewRoot[projectconfig.Config](modularconfig.Options[projectconfig.Config]{
		AppName:     "user",
		DefaultFile: "./config/user/config.yaml",
		EnvPrefix:   "USER",
		Run:         run,
	})
	command.SetContext(ctx)
	command.SilenceErrors = true
	command.SilenceUsage = true
	if err := command.Execute(); err != nil {
		fmt.Fprintf(os.Stderr, "application exited: %v\n", err)
		os.Exit(1)
	}
}

func run(ctx context.Context, cfg *projectconfig.Config) error {
	// cfg 已由 config.NewRoot 加载;日志固定是第二个初始化步骤。
	loggerManager, err := log.NewLoggerManager(&cfg.Logging, log.WithOutputConsole())
	if err != nil {
		return fmt.Errorf("create logger: %w", err)
	}
	restoreLogger := log.SetDefault(loggerManager.Logger())
	defer restoreLogger()
	defer loggerManager.Close(context.WithoutCancel(ctx))
	policy := modulartransport.NewPolicy(cfg.Name, modulartransport.WithLogger(loggerManager.Logger()))

	httpSrv, err := httpserver.NewServer(&cfg.HTTP, httpserver.WithPolicy(policy))
	if err != nil {
		return fmt.Errorf("create HTTP server: %w", err)
	}
	httpSrv.RegisterRoute(func(r *gin.Engine) {
		r.GET("/ping", func(c *gin.Context) {
			c.JSON(http.StatusOK, gin.H{"ok": true})
		})
	})

	node := core.NewServiceNode(cfg.Name, cfg.Version, httpSrv.Transport())

	application, err := app.NewApplication(
		ctx,
		&cfg.Application,
		loggerManager.Logger(),
		app.WithServiceNode(node),
		app.WithEndpoint(httpSrv),
	)
	if err != nil {
		return fmt.Errorf("create application: %w", err)
	}

	return application.Run()
}

运行时可以组合配置来源和覆盖参数:

user --config ./config/user/config.yaml \
  --remote etcd://10.0.0.1:2379/config/user \
  --http.port 18080

single 拓扑的进程配置会嵌套多个 svc,此时模块参数也带 svc 前缀,例如 --user.http.port--billing.redis.host

需要注册中心时,在 cmd 中构造 registrar 并注入:

registrar, err := registry.NewConsulRegistry("127.0.0.1:8500")
if err != nil {
	panic(err)
}

application, err := app.NewApplication(
	ctx,
	&cfg.Application,
	loggerManager.Logger(),
	app.WithServiceNode(node),
	app.WithRegistrar(registrar),
	app.WithEndpoint(httpSrv),
)

需要基础设施时,将其包装或直接构造成 core.Resource 后通过 app.WithResource(...) 注入。Resource.Setup 会在所有 endpoint 启动前执行,Resource.Close 会在 endpoint 停止后按反向顺序执行。

统一错误与多语言

业务包集中定义与语言无关、可复用的文案对象,调用时只绑定模板参数:

var UserNotFound = errs.Define(
	"USER_NOT_FOUND",
	errs.Template("user %v not found", errs.Name("user_id")),
)

func findUser(id string) error {
	return errs.NotFound(
		UserNotFound.With("user_id", id),
		errs.WithCause(errors.New("database row not found")),
		errs.WithField("user_id", id),
	)
}

每种语言使用一个 YAML 文件,文件名是 BCP 47 locale,例如 locales/zh-CN.yaml

UNKNOWN: "请求处理失败"
USER_NOT_FOUND: "用户 {{.user_id}} 不存在"

代码模板只接受 %v 变量槽和 %% 字面量百分号。%v 按顺序映射到后续 errs.Name;产品可以修改任意文字并调整 {{.name}} 的顺序,但不能增删或改名。缺少运行时参数时仅将对应槽位替换为 UNKNOWN,其余文案保持不变,同时记录诊断日志。

使用 err_template_gen 从业务代码批量创建或更新语言文件:

go install github.com/wplbyx/modular/packages/generate/cmd/err_template_gen@latest

err_template_gen \
  --root . \
  --packages ./internal/user/... \
  --out ./config/user/locales \
  --languages zh-CN,en-US

# CI 中只校验源码定义、reason 和槽位契约,不修改文件
err_template_gen --root . --out ./config/user/locales --languages zh-CN,en-US --check

重复生成会保留已有产品文案和注释,只追加新 reason。非法槽位、冲突定义、源码已删除但 YAML 仍存在的 reason 都会使命令失败,且验证失败时不会写入任何语言文件。

Catalog 和 Handler 在 cmd 层显式构造,并同时注入 HTTP 与 gRPC server:

catalog, err := errs.LoadCatalog(os.DirFS("."), "locales", "zh-CN")
if err != nil {
	return fmt.Errorf("load error catalog: %w", err)
}
errorHandler, err := errs.NewHandler(catalog, loggerManager.Logger())
if err != nil {
	return fmt.Errorf("create error handler: %w", err)
}

httpSrv, err := httpserver.NewServer(&cfg.HTTP, httpserver.WithErrorHandler(errorHandler))
grpcSrv, err := rpcserver.NewServer(&cfg.GRPC, register, rpcserver.WithErrorHandler(errorHandler))

HTTP handler 可通过 httpserver.Wrap(func(*gin.Context) error) 返回错误,也可使用 c.Error(err)。HTTP 从 Accept-Language、gRPC 从 accept-language metadata 选择文案。客户端只收到 codereason、本地化 message;cause、内部 fields、完整错误链和堆栈只写入注入的 Context Logger,并携带 request/trace/span 关联字段。

数据库连接

packages/infra/database 提供显式依赖注入的托管资源:

后端 Application Resource 配置
Bun/PostgreSQL bun.NewResource(cfg) configitem.Database{DSN: ...}
GORM gorm/postgres.NewResourcegorm/mysql.NewResourcegorm/clickhouse.NewResourcegorm/sqlite.NewResource configitem.Database{DSN: ...}
MongoDB mongo.NewResource(cfg) configitem.Mongo{URI: ...}

所有资源都基于 core.ManagedResource[T],同时实现 core.Resourcecore.Provider[T]。Application 负责 Setup/Close,repository 保存 Provider 并在处理请求时调用 Value();不要在 Application.Run 前提前取值。Redis 使用 redis.NewResource(cfg),Storage 使用 storage/resource.New(cfg)。数据库、Redis 和 HTTP client 不再提供包级全局实例。

GORM 方言由 cmd 装配层通过子包选择。SQLite 子包使用纯 Go 驱动,可在 CGO_ENABLED=0 下编译和测试。

健康检查与 HTTP client

HTTP server 默认 /health 只表示进程存活。通过 httpserver.WithReadiness(path, checkers...) 注入 health.Checker 后,就绪接口返回 200/503,且 Transport.HealthPath 会指向 readiness 路径。流式响应可将 WriteTimeout 设为 httpserver.NoWriteTimeout

HTTP client 是显式构造的 *httpclient.Client,主接口为 Do(*http.Request)。重试仅适用于可重放的幂等请求;POST/PATCH 需要 Idempotency-Key 或自定义 RetryPolicy

推荐项目分层

v2 脚手架把基础设施框架和业务实现分开。第一阶段由 CLI 生成可编译的进程、配置、transport、Resource 和 wiring;第二阶段由 Agent 根据需求写 proto、端口和稳定错误码;第三阶段再实现业务并用单测保证行为。

<project>/
  .modular/
    manifest.json            # 文件所有权、生成哈希、模板版本和最小生成来源
    profile.toml             # 当前项目的附加检查策略
    make/modular.mk          # 受管 Make 目标
    tool/                    # 项目内可迁移的脚手架及模板
  cmd/
    <process>/main.go        # 受管入口
    <process>/framework.gen.go
  config/
    <project>/               # single 拓扑进程配置,由 skill 聚合生成
      config.gen.go
      config.yaml
    <svc>/
      config.gen.go          # transport/Resource 字段,受管
      config.go              # 一次性模板,之后由用户维护
      config.yaml            # 受管配置片段;service 拓扑直接作为运行配置
  common/                    # protoc 生成物,不手写;目录结构镜像 proto/
    <svc>/
      <svc>.pb.go
      <svc>_grpc.pb.go
      <surface>.pb.go
      <surface>_grpc.pb.go
  internal/
    platform/wiring/
      framework.gen.go       # transport hook 和 Resource Provider 类型
      business.go            # 一次性 wiring 接缝,由 Agent/用户维护
    <svc>/
      api/                   # 入站适配器:HTTP/gRPC/event 映射到对应接口面
        <surface>/           # admin / management / platform / openapi ...
          grpc.go
          http.go
          event.go
          v1/                # 可选:只有 proto 接口面引入版本时才出现
      app/                   # 默认实现 pb XxxServiceServer,并编排用例:直接调用Repository(简单的MVC), 转到调用domain走复杂的业务逻辑
        <surface>/           # 与 api/<surface> 对齐
          adapter.go         # 业务相关接口在这里定义:可读写分离,简单的直接repository层实现(走dto), 复杂的依赖 domain 接口。
          server.go          # 该接口面的 pb server 实例和依赖注入, 简单的可以直接调用 repository/ 实现
          <method>.go        # 一个 pb 方法一个文件,例如 CreateUser -> create_user.go
          v1/                # 可选:版本化 pb server adapter
      domain/
        adapter.go           # 领域相关接口,仓储接口/端口:command/query 可拆分
        entity/              # 充血领域对象、聚合根,内聚的逻辑
        service/             # 领域逻辑?这里是什么领域逻辑
      repository/            # 出站适配器:DB/Redis/client/storage 等脏活累活 (内部的包随便拆分[都是基础设施])
        app/                 # app 层简单的接口实现
        domain/              # domain 层业务逻辑的接口实现
        dto/                 # model 数据的操作的封装实现
        model/               # 数据模型
  proto/
    <svc>/
      <svc>.proto            # 按业务模块分包;默认不再细分 v1/v2
      <surface>.proto        # 可选:admin / management / platform 等接口面      
  go.mod    

约束:

  • service add 必须显式选择 --transport http|grpc;未选择的 transport、domain、repository 和 event 层不会生成。
  • managed 文件只有在当前哈希与 manifest 一致时才更新;scaffold-once 文件创建后归用户和 Agent 维护。
  • .modular/manifest.json 不是架构决策文档,只记录脚手架重放所需的所有权、哈希、模板版本和最小来源,用于冲突检测、幂等同步、升级和安全删除。
  • 跨领域调用走生成的 pb client,不导入其他领域的 internal/
  • proto/common/ 都按业务模块分包:proto/<svc>/... 生成到 common/<svc>/...,与 internal/<svc>/... 对齐;这里的 <svc> 是最外层业务模块名。
  • 一个业务模块可以有多个接口面(surface),例如 adminmanagementplatformopenapi。接口面是外部契约维度,不是领域模型维度。
  • surface 名称也是 Go 包名,使用 lower_snake_case,不使用连字符,默认不带版本后缀。
  • 多接口面默认按 proto/<svc>/<surface>.protocommon/<svc>/<surface>.pb.gointernal/<svc>/api/<surface>internal/<svc>/app/<surface> 对齐。单接口面可以继续使用 proto/<svc>/<svc>.proto
  • 当前默认不严格区分 v1/v2;未来如果某个接口面引入版本,优先放在 proto/<svc>/<surface>/v1,并镜像到 common/<svc>/<surface>/v1internal/<svc>/api/<surface>/v1internal/<svc>/app/<surface>/v1
  • common/ 是生成目录,不手写 .pb.go_grpc.pb.go
  • api 属于基础设施入站适配层,只做流量入口、路由/订阅、请求解析和映射,不放业务规则。
  • app/<surface> 默认实现生成的 XxxServiceServer,同时编排用例流程。简单 CRUD/MVC 流程可以依赖本包 adapter.go 里定义的 QueryRepository / CommandRepository,由 repository/app 直接实现;复杂业务流程可以依赖 internal/<svc>/domain 里的领域定义和端口。
  • app/<surface>/server.go 放该接口面的 server 类型、构造函数和依赖注入;每个 pb 方法放到独立文件,文件名与方法名一一对应(Go 文件名用 snake_case,例如 CreateUser -> create_user.go)。
  • service/ 不是默认层。只有当 pb 契约和内部用例模型明显分离、多版本 pb 需要复用同一组用例、或一个 pb service 需要组合多个 app 子模块时,才引入 service 作为额外适配层。
  • 简单 CRUD 把端口放在 app/<surface>,不创建空 domain;只有不变量、聚合协调、策略或事务规则需要领域接缝时才创建 domain
  • app/<surface>/adapter.godomain/adapter.go 是两类接口边界:前者服务简单用例,后者服务复杂领域模型。两者的实现都交给 repository 层。
  • repository 是基础设施实现区:repository/app 实现 app 层简单接口,repository/domain 实现 domain 层复杂端口,repository/dtorepository/model 按需放 DTO、持久化模型和 ORM/BSON tag。
  • internal/ 的业务逻辑不直接依赖 github.com/wplbyx/modular/packages/app.Application
  • 项目自己的 svc Config 聚合类型放在 config/<svc>,并通过 GetConfigFlagSpecsWithPrefix 实现 FlagProvider
  • service 拓扑由 cmd/<svc> 使用 NewRoot[config/<svc>.Config];single 拓扑由 cmd/<project> 使用生成的 config/<project>.Config,其中嵌套各 svc 配置。
  • single 的 config/<project>/config.gen.go|yaml 是受管文件;业务配置以 config/<svc> 为来源,重新执行 scaffold/resource 命令会刷新进程聚合配置。
  • cmd 可以依赖 github.com/wplbyx/modular/packages/*,负责把资源、endpoint 和业务实现接起来。
  • 未实现的契约必须显式返回 Unimplemented 并携带 modular:contract-unimplemented,不能返回空成功响应。
  • 框架阶段通过 make scaffold-check,契约阶段通过 make contract-check,业务完成后通过 make verify;覆盖率只报告,不设通用数值门槛。

Agent 使用方式

仓库内提供一个顶层 modular skill。SKILL.md 负责路由 init、CRUD、domain、resource、migration 和 audit 工作流;确定性的框架改动由 modular.py 完成,业务边界和业务代码由 Agent 根据需求编写。

默认使用原子复制安装;只有本地开发 skill 时才使用符号链接:

./install-modular-skill.sh modular
./install-modular-skill.sh modular --development-link
.\install-modular-skill.ps1 modular
.\install-modular-skill.ps1 modular -DevelopmentLink

可以这样让 Agent 使用它:

使用 modular skill 初始化一个 single 拓扑项目,项目名叫 myapp
使用 modular skill 给当前项目添加只暴露 HTTP 的 user svc
使用 modular skill 为 user 设计简单 CRUD 契约,不要创建 domain 空壳
使用 modular skill 为订单聚合设计领域对象、端口和稳定错误码
使用 modular skill 给项目接入 redis resource
使用 modular skill 审计当前项目结构
使用 modular skill 把 single 拓扑迁移为每个 svc 一个进程

确定性命令:

命令 用途
`init --topology single service`
service add/remove 管理 svc 配置和进程装配;添加时必须显式选择 transport。
transport add/remove 修改已有 svc 的 HTTP/gRPC 选择。
resource add/remove 管理 DB、Redis、Storage、Telemetry 和进程内 EventBus 资源装配。
sync / prune 幂等同步受管文件,或安全删除不再需要且未被修改的受管文件。
migrate topology 只迁移受管的 cmd/config 进程文件,保留业务 wiring 和业务包。
project upgrade 更新项目内工具和已发布的 modular 依赖版本。
doctor / verify 执行只读审计和 framework/contract/complete 阶段门禁。
gen / coverage 运行 buf 生成和无数值门槛的覆盖率报告。

Agent 处理这些任务时会按需读取 agent/modular/references/

  • references/workflows/init.md
  • references/workflows/crud.md
  • references/workflows/domain.md
  • references/workflows/resource.md
  • references/workflows/migration.md
  • references/workflows/audit.md

开发与验证

仓库是纯 Go 项目,没有 Makefile 或 CI 配置。常用命令:

go build ./...
go test ./...
go test ./packages/app -v
go vet ./...
gofmt -l .
go mod tidy

编辑配置结构体时注意 packages/config 下存在 //go:generate 指令,依赖外部工具 gomodifytags。只有确实需要刷新 mapstructure tag 时才运行:

go generate ./packages/config/...

重要现实情况

  • 仓库自身没有 .proto_pb.go、buf/protoc 生成链路;proto-first 是下游业务项目的约定,agent/modular 会为下游项目生成骨架。
  • app 不导入 transport,只接收 core.Endpointcore.Resource
  • 请求边缘和需要稳定业务 reason 的错误使用 packages/errs;生命周期初始化/关闭错误仍使用 fmt.Errorf("...: %w", err)errors.Join
  • 所有日志方法强制接收 context.Contextlog.Default() 未安装时为 no-op。进程必须在配置加载后第二步创建 LoggerManager,再由 cmd 显式安装默认 logger。
  • storage 当前只有 diskoss 两类实现;OSS 使用 alibabacloud-oss-go-sdk-v2,不要引入 v1 SDK。
  • infra/cache/redisinfra/databasetransport/client 保留包级全局能力,但应用装配时应优先把返回实例作为依赖注入。

Directories

Path Synopsis
packages
app
buildinfo
Package buildinfo reads application identity and Go build metadata without global configuration.
Package buildinfo reads application identity and Go build metadata without global configuration.
eventbus
Package eventbus provides an in-process, ordered, at-most-once event bus.
Package eventbus provides an in-process, ordered, at-most-once event bus.
health
Package health provides composable, transport-independent readiness checks.
Package health provides composable, transport-independent readiness checks.
idgen
Package idgen defines opaque business ID generation and node-lease seams.
Package idgen defines opaque business ID generation and node-lease seams.
idgen/resource
Package resource adapts ID generators to the modular Resource lifecycle.
Package resource adapts ID generators to the modular Resource lifecycle.
idgen/snowflake
Package snowflake provides a configurable leased-node Snowflake generator.
Package snowflake provides a configurable leased-node Snowflake generator.
idgen/uuidv7
Package uuidv7 provides a coordination-free UUID version 7 ID generator.
Package uuidv7 provides a coordination-free UUID version 7 ID generator.
infra/storage/resource
Package resource provides Application lifecycle composition for storage backends.
Package resource provides Application lifecycle composition for storage backends.
log
Package log provides the process logger used by modular modules.
Package log provides the process logger used by modular modules.
metadata
Package metadata provides immutable request metadata with explicit propagation scopes.
Package metadata provides immutable request metadata with explicit propagation scopes.
pool
Package pool provides a bounded, observable worker pool for asynchronous tasks.
Package pool provides a bounded, observable worker pool for asynchronous tasks.
transport
Package transport defines protocol-neutral transport policy.
Package transport defines protocol-neutral transport policy.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL