This commit is contained in:
+53
-12
@@ -53,7 +53,18 @@ func Runner(timer *model.Timer) {
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// ExecuteRule 执行单个规则并记录执行日志
|
||||
// NewTask 组装执行一条规则所需的输入:规则本体 + 从数据库取出的关联账号。
|
||||
//
|
||||
// 数据库访问只发生在这一层,driver 拿到的 task 已经是自包含的。
|
||||
func NewTask(rule *model.Rule) (*model.RuleTask, error) {
|
||||
account, err := db.GetAccount(rule.AccountID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &model.RuleTask{Rule: rule, Account: account}, nil
|
||||
}
|
||||
|
||||
// ExecuteRule 执行单条规则并记录执行日志
|
||||
func ExecuteRule(rule *model.Rule, trigger string) error {
|
||||
ctx, cancel := retry.ExecutionContext()
|
||||
defer cancel()
|
||||
@@ -62,24 +73,54 @@ func ExecuteRule(rule *model.Rule, trigger string) error {
|
||||
|
||||
// ExecuteRuleWithContext 使用给定 context 执行规则,手动测试时可传入较短的超时
|
||||
func ExecuteRuleWithContext(ctx context.Context, rule *model.Rule, trigger string) error {
|
||||
err := GetGlobalExecutorRegistry().Execute(ctx, rule)
|
||||
|
||||
message := "执行成功"
|
||||
if err != nil {
|
||||
message = err.Error()
|
||||
log.Printf("执行规则失败 [ID: %d, Type: %s]: %v", rule.ID, rule.Type, err)
|
||||
}
|
||||
|
||||
logstore.Record(&model.ExecutionLog{
|
||||
task, err := NewTask(rule)
|
||||
return execTask(ctx, task, err, &model.ExecutionLog{
|
||||
UID: rule.UID,
|
||||
RuleID: rule.ID,
|
||||
RuleName: rule.Name,
|
||||
RuleType: rule.Type,
|
||||
TimerID: rule.TimerID,
|
||||
Trigger: trigger,
|
||||
Success: err == nil,
|
||||
Message: message,
|
||||
})
|
||||
}
|
||||
|
||||
// ExecuteGatewayRuleWithContext 执行一条消息网关规则,日志里带上网关信息。
|
||||
//
|
||||
// 与定时器规则走同一条执行链路,区别只有触发来源与日志字段。
|
||||
func ExecuteGatewayRuleWithContext(ctx context.Context, rule *model.GatewayRule, trigger string) error {
|
||||
task, err := NewTask(rule.AsRule())
|
||||
return execTask(ctx, task, err, &model.ExecutionLog{
|
||||
UID: rule.UID,
|
||||
RuleName: rule.Name,
|
||||
RuleType: rule.Type,
|
||||
GatewayID: rule.GatewayID,
|
||||
GatewayRuleID: rule.ID,
|
||||
Trigger: trigger,
|
||||
})
|
||||
}
|
||||
|
||||
// execTask 执行规则并写入执行日志。
|
||||
//
|
||||
// taskErr 是组装输入时的错误(例如账号已被删除):这时不会走到 driver,
|
||||
// 但同样要留下一条失败日志,方便用户在 WebUI 上看到原因。
|
||||
func execTask(ctx context.Context, task *model.RuleTask, taskErr error, entry *model.ExecutionLog) error {
|
||||
if taskErr != nil {
|
||||
return record(entry, taskErr)
|
||||
}
|
||||
|
||||
log.Printf("执行规则 [%s] %s (触发来源: %s)", entry.RuleType, entry.RuleName, entry.Trigger)
|
||||
return record(entry, GetGlobalExecutorRegistry().Execute(ctx, task))
|
||||
}
|
||||
|
||||
// record 写入执行日志并返回原始错误
|
||||
func record(entry *model.ExecutionLog, err error) error {
|
||||
entry.Success = err == nil
|
||||
entry.Message = "执行成功"
|
||||
if err != nil {
|
||||
entry.Message = err.Error()
|
||||
log.Printf("执行规则失败 [%s] %s: %v", entry.RuleType, entry.RuleName, err)
|
||||
}
|
||||
|
||||
logstore.Record(entry)
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user