feat: 添加数据库集成、定时任务调度器和事件Hook体系
- 新增数据库配置项(DB_TYPE, DB_HOST, DB_PORT等),支持MySQL和PostgreSQL - 集成GORM实现数据库连接和自动迁移功能 - 添加定时任务调度器(cmd/scheduler),基于robfig/cron实现秒级调度 - 实现事件Hook体系,支持同步/异步处理和优先级排序 - 更新构建脚本,编译server、cli、scheduler三个二进制文件 - 配置systemd服务管理定时任务调度器 - 重构项目结构,新增crontab和hooks目录模块 - 更新README文档,完善各组件使用说明和部署配置
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
package hooks
|
||||
|
||||
import "context"
|
||||
|
||||
// EventType 业务事件类型,按项目需求在此扩展
|
||||
type EventType string
|
||||
|
||||
// Handler 事件处理器接口
|
||||
type Handler interface {
|
||||
Handle(ctx context.Context, event EventType, payload *EventPayload) error
|
||||
}
|
||||
|
||||
// HandlerFunc 函数适配器,方便用匿名函数注册 handler
|
||||
type HandlerFunc func(ctx context.Context, event EventType, payload *EventPayload) error
|
||||
|
||||
func (f HandlerFunc) Handle(ctx context.Context, event EventType, payload *EventPayload) error {
|
||||
return f(ctx, event, payload)
|
||||
}
|
||||
|
||||
// EventPayload 事件携带的上下文信息
|
||||
type EventPayload struct {
|
||||
UserID int
|
||||
Extra map[string]any
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package hooks
|
||||
|
||||
var defaultManager = NewManager()
|
||||
|
||||
func DefaultManager() *Manager {
|
||||
return defaultManager
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package hooks
|
||||
|
||||
import (
|
||||
"apiServer_service/utils/logger"
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type handlerWithMeta struct {
|
||||
priority int
|
||||
async bool
|
||||
h Handler
|
||||
}
|
||||
|
||||
type Manager struct {
|
||||
mu sync.RWMutex
|
||||
handlers map[EventType][]handlerWithMeta
|
||||
}
|
||||
|
||||
func NewManager() *Manager {
|
||||
return &Manager{
|
||||
handlers: make(map[EventType][]handlerWithMeta),
|
||||
}
|
||||
}
|
||||
|
||||
// Register 同步注册,优先级 0
|
||||
func (m *Manager) Register(event EventType, h Handler) {
|
||||
m.RegisterWithOptions(event, 0, false, h)
|
||||
}
|
||||
|
||||
// RegisterWithPriority 指定优先级(同步)
|
||||
func (m *Manager) RegisterWithPriority(event EventType, priority int, h Handler) {
|
||||
m.RegisterWithOptions(event, priority, false, h)
|
||||
}
|
||||
|
||||
// RegisterAsync 异步注册,优先级 0
|
||||
func (m *Manager) RegisterAsync(event EventType, h Handler) {
|
||||
m.RegisterWithOptions(event, 0, true, h)
|
||||
}
|
||||
|
||||
// RegisterWithOptions 核心注册:优先级 + 同步/异步
|
||||
func (m *Manager) RegisterWithOptions(event EventType, priority int, async bool, h Handler) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
m.handlers[event] = append(m.handlers[event], handlerWithMeta{
|
||||
priority: priority,
|
||||
async: async,
|
||||
h: h,
|
||||
})
|
||||
}
|
||||
|
||||
// Trigger 触发事件,按优先级从高到低执行
|
||||
func (m *Manager) Trigger(ctx context.Context, event EventType, payload *EventPayload) {
|
||||
m.mu.RLock()
|
||||
hs := m.handlers[event]
|
||||
m.mu.RUnlock()
|
||||
|
||||
if len(hs) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
sorted := make([]handlerWithMeta, len(hs))
|
||||
copy(sorted, hs)
|
||||
sort.SliceStable(sorted, func(i, j int) bool {
|
||||
return sorted[i].priority > sorted[j].priority
|
||||
})
|
||||
|
||||
for _, hm := range sorted {
|
||||
if hm.async {
|
||||
go func(hm handlerWithMeta) {
|
||||
if err := hm.h.Handle(ctx, event, payload); err != nil {
|
||||
logger.Error("Hook", fmt.Sprintf("async event=%s err=%v", event, err))
|
||||
}
|
||||
}(hm)
|
||||
} else {
|
||||
if err := hm.h.Handle(ctx, event, payload); err != nil {
|
||||
logger.Error("Hook", fmt.Sprintf("event=%s err=%v", event, err))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package registers
|
||||
|
||||
import (
|
||||
"apiServer_service/hooks"
|
||||
)
|
||||
|
||||
// RegisterHooks 注册所有事件 handler,新增 hook 在此添加
|
||||
func RegisterHooks(m *hooks.Manager) {
|
||||
// 示例:
|
||||
// m.Register(hooks.EventType("order_paid"), hooks.HandlerFunc(OnOrderPaid))
|
||||
// m.RegisterAsync(hooks.EventType("user_registered"), hooks.HandlerFunc(SendWelcomeEmail))
|
||||
}
|
||||
Reference in New Issue
Block a user