调整项目架构,让框架更优化

This commit is contained in:
2026-07-20 21:39:01 +08:00
parent 987b16fd41
commit 121928733b
16 changed files with 866 additions and 689 deletions

181
factory/lifecycle.go Normal file
View File

@@ -0,0 +1,181 @@
package factory
import (
"errors"
"fmt"
"git.toowon.com/jimmy/go-common/email"
"git.toowon.com/jimmy/go-common/i18n"
"git.toowon.com/jimmy/go-common/logger"
"git.toowon.com/jimmy/go-common/sms"
"git.toowon.com/jimmy/go-common/storage"
"github.com/redis/go-redis/v9"
"gorm.io/gorm"
)
// Module 可预热的模块标识(用于 Warmup
type Module string
const (
ModuleLogger Module = "logger"
ModuleDatabase Module = "database"
ModuleRedis Module = "redis"
ModuleStorage Module = "storage"
ModuleEmail Module = "email"
ModuleSMS Module = "sms"
ModuleI18n Module = "i18n"
)
// MustInit 从配置文件初始化全局 Factory失败则 panic适合 main 启动)
func MustInit(filePath string, opts ...Option) *Factory {
if err := Init(filePath, opts...); err != nil {
panic(err)
}
return Default()
}
// Warmup 按需预热模块:配置缺失或连接失败时立即返回错误(适合启动期 fail-fast
func (f *Factory) Warmup(modules ...Module) error {
if f == nil {
return fmt.Errorf("factory is nil")
}
for _, m := range modules {
var err error
switch m {
case ModuleLogger:
_, err = f.Logger()
case ModuleDatabase:
_, err = f.Database()
case ModuleRedis:
_, err = f.Redis()
case ModuleStorage:
_, err = f.Storage()
case ModuleEmail:
_, err = f.Email()
case ModuleSMS:
_, err = f.SMS()
case ModuleI18n:
_, err = f.I18n()
default:
return fmt.Errorf("unknown module: %s", m)
}
if err != nil {
return fmt.Errorf("warmup %s: %w", m, err)
}
}
return nil
}
// Close 关闭已创建的有状态模块email / sms / redis / database / logger
// 可重复调用;未初始化的模块会被跳过。
func (f *Factory) Close() error {
if f == nil {
return nil
}
f.mu.Lock()
defer f.mu.Unlock()
var errs []error
if f.email != nil {
if err := f.email.Close(); err != nil {
errs = append(errs, fmt.Errorf("email: %w", err))
}
f.email = nil
}
if f.sms != nil {
if err := f.sms.Close(); err != nil {
errs = append(errs, fmt.Errorf("sms: %w", err))
}
f.sms = nil
}
if f.redis != nil {
if err := f.redis.Close(); err != nil {
errs = append(errs, fmt.Errorf("redis: %w", err))
}
f.redis = nil
}
if f.db != nil {
if sqlDB, err := f.db.DB(); err != nil {
errs = append(errs, fmt.Errorf("database: %w", err))
} else if err := sqlDB.Close(); err != nil {
errs = append(errs, fmt.Errorf("database: %w", err))
}
f.db = nil
}
if f.logger != nil {
if err := f.logger.Close(); err != nil {
errs = append(errs, fmt.Errorf("logger: %w", err))
}
f.logger = nil
}
// 中间件链依赖 logger/i18n关闭后允许下次重新组装
f.chain = nil
return errors.Join(errs...)
}
// MustLogger 获取日志对象;失败则 panic适合启动期注入
func (f *Factory) MustLogger() *logger.Logger {
l, err := f.Logger()
if err != nil {
panic(err)
}
return l
}
// MustDatabase 获取数据库连接;失败则 panic适合启动期注入
func (f *Factory) MustDatabase() *gorm.DB {
db, err := f.Database()
if err != nil {
panic(err)
}
return db
}
// MustRedis 获取 Redis 客户端;失败则 panic适合启动期注入
func (f *Factory) MustRedis() *redis.Client {
c, err := f.Redis()
if err != nil {
panic(err)
}
return c
}
// MustStorage 获取存储对象;失败则 panic适合启动期注入
func (f *Factory) MustStorage() storage.Storage {
s, err := f.Storage()
if err != nil {
panic(err)
}
return s
}
// MustEmail 获取邮件客户端;失败则 panic适合启动期注入
func (f *Factory) MustEmail() *email.Email {
e, err := f.Email()
if err != nil {
panic(err)
}
return e
}
// MustSMS 获取短信客户端;失败则 panic适合启动期注入
func (f *Factory) MustSMS() *sms.SMS {
s, err := f.SMS()
if err != nil {
panic(err)
}
return s
}
// MustI18n 获取国际化对象;失败则 panic适合启动期注入
func (f *Factory) MustI18n() *i18n.I18n {
i, err := f.I18n()
if err != nil {
panic(err)
}
return i
}