Documentation
¶
Overview ¶
Package rule 实现规则引擎(可编排状态管理):事件 → 有界 channel → 规则 worker (priority 首中匹配)→ 状态/冷却/权重更新。scheduler.MarkResult 的硬编码状态机 由本包替代:scheduler 只做禁用守卫 + 事件投递(条件投递),动作应用经 SetApply 注册的回调完成(更新快照 + EWMA + 异步回写,属 scheduler 侧)。
Index ¶
- func Apply(t domain.RuleThen, ev Event) (*domain.AccountStatus, *time.Time, *int)
- func Match(w domain.RuleWhen, ev Event, wc windowSnapshot) bool
- func UnifiedMessage(then domain.RuleThen, upstream string) (string, bool)
- func ValidateThen(t domain.RuleThen) error
- func ValidateWhen(w domain.RuleWhen) error
- type ApplyFunc
- type Config
- type Event
- type Kind
- type RuleEngine
- func (e *RuleEngine) Classify(ev Event) (then domain.RuleThen, punish bool)
- func (e *RuleEngine) Close(ctx context.Context) error
- func (e *RuleEngine) Enqueue(ev Event)
- func (e *RuleEngine) Flush(ctx context.Context)
- func (e *RuleEngine) HandleEvent(ctx context.Context, ev Event)
- func (e *RuleEngine) Name() string
- func (e *RuleEngine) NeedsOKEvents() bool
- func (e *RuleEngine) Reload(ctx context.Context) error
- func (e *RuleEngine) ReloadRules(ctx context.Context) error
- func (e *RuleEngine) SetApply(fn ApplyFunc)
- func (e *RuleEngine) Start(ctx context.Context) error
- func (e *RuleEngine) Stats() any
- type RuleEngineStats
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Apply ¶
Apply 解析 then 动作:cooldownUntil = OccurredAt + 解析后的 cooldown; cooldown 未配但事件带 ResetAt 时用 ResetAt(M2 残留:resetAt 语义保留)。 Status 为 nil 返回 nil 状态 = 只改权重(或只改冷却)。
func Match ¶
Match 规则 when 与事件(+ 窗口计数)是否匹配:等值/子串/计数阈值/比例。 窗口比例 = t429(或 failure) / (ok+failure+t429),仅当 total ≥ CountTotalGE 时参与判定(样本不足不满足,ValidateWhen 已保证比例类必配 CountTotalGE, 此处仍防御)。
func UnifiedMessage ¶
UnifiedMessage 统一公式 msg=CustomMessage!=nil?*CustomMessage:upstream 响应与 sanitize 同源(I-3),代理日志保留原文边界另述 TODO: upstream param unused — kept for formula parity (honest return would be upstream when CustomMessage==nil; callers currently handle passthrough separately)
func ValidateThen ¶
ValidateThen then 动作校验:全空 Then{} 合法=纯透传(匹配后码/文双透、上游原样返回、零惩罚); 其余:status 合法枚举;cooldown 可 time.ParseDuration 解析且 > 0;weight ∈ [0,100]; ResponseCode!=nil 需 400-599;CustomMessage==ptr("") 拒绝。指针即意图,nil=透传; seed-4xx-400 直插 store 的 Then{} 与用户规则 Then{} 语义等价(零惩罚全透)。
func ValidateWhen ¶
ValidateWhen when 语义校验(字段白名单/未知字段由 service 层 JSON 反序列化 DisallowUnknownFields 挡下;此处查语义):
- kind 必须为 ok/429/4xx/5xx/network 之一(error 已删除——4xx 独立、 连接级独立 network,用户裁决)
- kind=ok 与 error_message_contains 不兼容(ok 事件错误信息恒空 → 永不命中)
- 计数阈值 ≥ 0、window_seconds ≥ 1
- 比例 ∈ [0,1] 且必须配 count_total_ge(比例样本下限)
Types ¶
type ApplyFunc ¶
type ApplyFunc func(aid int64, st *domain.AccountStatus, cooldownUntil *time.Time, weight *int, errMsg string)
ApplyFunc 动作应用回调(由 scheduler 注册):st 为 nil = 不改状态(只改权重); cooldownUntil 为 nil = 不设冷却;weight 为 nil = 不改权重。errMsg 为事件 错误文本(error_message_contains 已匹配;供 last_error 落库——部署故障 修复:scheduler 侧截断 500 后回写)。
type Event ¶
type Event struct {
AccountID int64
TemplateID int64
GroupID *int64
Model string
Kind Kind
HTTPStatus *int
ErrorMessage string
ResetAt *time.Time
OccurredAt time.Time // 零值由引擎填充为当前时间
}
Event 请求结果事件(由 scheduler.MarkResult 构造投递)。
type Kind ¶
type Kind int
Kind 事件类别(单一 kind 概念;连接级/5xx 分流由 scheduler.RuleKindOf 在 调用点完成——scheduler 不再有第二套枚举)。
type RuleEngine ¶
type RuleEngine struct {
// contains filtered or unexported fields
}
RuleEngine 规则引擎:加载 enabled 规则(priority 升序)、逐规则首中匹配、 窗口计数维护与 worker 消费循环(Name/Start/Close 见 worker.go)。
func New ¶
func New(cfg Config, store repository.RuleStore, log *logx.Logger) *RuleEngine
New 只建结构(不加载规则、不注册 apply——分别由 Reload/SetApply 显式完成)。
func (*RuleEngine) Classify ¶
func (e *RuleEngine) Classify(ev Event) (then domain.RuleThen, punish bool)
Classify 事件分类决策(错误分支响应/投递决策——scheduler 包装调用,用户面 err_logs 行级脱敏亦复用):遍历 enabled 规则(priority 升序首中),首个 "非窗口条件维度"(kind/http_status/message_contains/account/template/group/ model)命中者决定结果。窗口条件规则(count_*/ratio_*,ruleNeedsWindow)依赖 历史计数,预判不可得——按"可能命中"保守处理(不参与判定,窗口阈值由 worker Match 精确裁决;prejudge 命中 → punish 保证事件投递,worker 再精确应用)。 指针即意图:then.ResponseCode nil=透传上游码,non-nil=覆写;then.CustomMessage nil=透传上游文,non-nil=覆写;头透传与 kind 解耦(ResponseCode==nil 才透)。 返回 then 值拷贝(调用方只读不得修改)与 punish(true = 命中规则有状态动作 Status/Weight/Cooldown 任一非 nil——应投递 MarkResult;漏判 Cooldown 则 cooldown-only 规则永不投递,冷却静默丢弃, 2026-08-19 缺陷 1 根因)。无命中 → (domain.RuleThen{}, false)(默认归一 502+generic,安全默认 ——不认识的错误不透传)。 零分配:仅读规则集切片(RLock 快照)+ 字符串比较。
func (*RuleEngine) Close ¶
func (e *RuleEngine) Close(ctx context.Context) error
Close 排空剩余事件(限时,复用 scheduler.Close 模式);幂等, 未 Start 时也可安全排空。循环本身随 Start 的 ctx 取消而退出。
func (*RuleEngine) Enqueue ¶
func (e *RuleEngine) Enqueue(ev Event)
Enqueue 投递事件:有界 channel,满则丢弃(dropped 原子计数)。热点修复 B: 逐条 Warn → 阈值告警(errlog 同构)——丢弃累计 ≥ ruleDropWarnThreshold 且 边沿未告警 → Warn 恰好一次(带累计数),不再刷屏。热路径纪律:丢弃路径 仅两个原子操作(Add + CompareAndSwap),零分配;日志只在阈值跨越时产生。
func (*RuleEngine) Flush ¶
func (e *RuleEngine) Flush(ctx context.Context)
Flush 同步排空队列:处理完当前队列中的全部事件后返回(测试与优雅关闭用)。 幂等,未 Start 时也可安全排空。
func (*RuleEngine) HandleEvent ¶
func (e *RuleEngine) HandleEvent(ctx context.Context, ev Event)
HandleEvent 同步处理单个事件:窗口计数 → 逐规则 Match(首中)→ ApplyFunc。 worker 消费循环与测试共用。命中不清零窗口计数(C2)——滑动自然衰减, 升级阶梯(如 60s 内 ≥5 error → 更重惩罚)不被低阈值规则清零阻断。 未命中仅更新计数。
func (*RuleEngine) Name ¶
func (e *RuleEngine) Name() string
Name 满足 worker.Worker 契约(Global Constraints #5)。
func (*RuleEngine) NeedsOKEvents ¶
func (e *RuleEngine) NeedsOKEvents() bool
NeedsOKEvents 规则表中是否存在需要 ok 事件投递的规则(when.kind 为 nil 或 "ok")—— scheduler 据此条件投递(C1:种子恢复规则 kind=ok 必须投递,否则成功恢复永不触发)。
func (*RuleEngine) Reload ¶
func (e *RuleEngine) Reload(ctx context.Context) error
Reload 全量加载 enabled 规则(priority 升序);空表先写种子(seedRules)。 失败返回 error——规则表是状态管理唯一路径,main 收到错误即 fatalf。
func (*RuleEngine) ReloadRules ¶
func (e *RuleEngine) ReloadRules(ctx context.Context) error
ReloadRules 规则表全量重载(invalidate.RulesReloader 适配,#14 T3a 装配 invalidate.Config.Rules):与 Reload 同一实现——重载清窗口计数,全实例同步 执行语义(设计文档 §1.5,NOTIFY Rules:true 远端变更触发)。
func (*RuleEngine) SetApply ¶
func (e *RuleEngine) SetApply(fn ApplyFunc)
SetApply 注册动作应用回调(scheduler 构造期注入;可重复调用覆盖)。
func (*RuleEngine) Start ¶
func (e *RuleEngine) Start(ctx context.Context) error
Start 启动事件消费循环(含周期性窗口清理);重复 Start 返回错误(幂等)。
func (*RuleEngine) Stats ¶
func (e *RuleEngine) Stats() any
Stats 满足 handler.StatsProvider(独立于 worker.Worker 契约;装配链路见 internal/handler/ops.go 文件头)。
type RuleEngineStats ¶
type RuleEngineStats struct {
Queued int `json:"queued"` // 队列积压事件数
QueueCap int `json:"queue_cap"` // 事件队列容量(丢弃阈值)
Dropped int64 `json:"dropped"` // 队列满丢弃累计(atomic.Uint64 转 int64——JSON 数字精度)
DropWarnThreshold int64 `json:"drop_warn_threshold"` // 丢弃告警阈值(包级 var 直读)
}
RuleEngineStats 规则引擎状态(队列占用 + 事件丢弃累计)。