Skip to content

Commit 5ffcbb3

Browse files
committed
fix sched
1 parent fc90a6f commit 5ffcbb3

2 files changed

Lines changed: 90 additions & 6 deletions

File tree

backend/modules/evaluation/domain/service/expt_template_impl.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,10 @@ func (e *ExptTemplateManagerImpl) Create(ctx context.Context, param *entity.Crea
196196
}
197197

198198
// 创建模板成功后同步底层调度任务(仅 SourceType=Evaluation 生效)
199+
logs.CtxInfo(ctx, "[expt_template_sched] sync after Create, space_id=%d, template_id=%d, has_expt_source=%v, has_scheduler=%v",
200+
template.GetSpaceID(), template.GetID(),
201+
template.ExptSource != nil,
202+
template.ExptSource != nil && template.ExptSource.Scheduler != nil)
199203
e.syncSchedulerForTemplate(ctx, template)
200204

201205
return template, nil
@@ -483,6 +487,10 @@ func (e *ExptTemplateManagerImpl) Update(ctx context.Context, param *entity.Upda
483487
}
484488

485489
// 更新模板成功后同步底层调度任务,覆盖 Scheduler 启停 / 频率变更 / SourceType 切换等场景
490+
logs.CtxInfo(ctx, "[expt_template_sched] sync after Update, space_id=%d, template_id=%d, has_expt_source=%v, has_scheduler=%v",
491+
updatedTemplate.GetSpaceID(), updatedTemplate.GetID(),
492+
updatedTemplate.ExptSource != nil,
493+
updatedTemplate.ExptSource != nil && updatedTemplate.ExptSource.Scheduler != nil)
486494
e.syncSchedulerForTemplate(ctx, updatedTemplate)
487495

488496
return updatedTemplate, nil
@@ -574,6 +582,8 @@ func (e *ExptTemplateManagerImpl) UpdateMeta(ctx context.Context, param *entity.
574582

575583
// CronActivate 翻转后需要同步底层调度任务
576584
if param.CronActivate != nil {
585+
logs.CtxInfo(ctx, "[expt_template_sched] sync after UpdateMeta (cron_activate flipped to %v), space_id=%d, template_id=%d",
586+
*param.CronActivate, updatedTemplate.GetSpaceID(), updatedTemplate.GetID())
577587
e.syncSchedulerForTemplate(ctx, updatedTemplate)
578588
}
579589

backend/modules/evaluation/domain/service/expt_template_schedule.go

Lines changed: 80 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,47 +41,121 @@ type schedulerCallbackPayload struct {
4141
// - 任何错误仅记录日志,不阻断模板创建/更新主流程
4242
func (e *ExptTemplateManagerImpl) syncSchedulerForTemplate(ctx context.Context, template *entity.ExptTemplate) {
4343
if e == nil || e.scheduleAdapter == nil || template == nil {
44+
logs.CtxWarn(ctx, "[expt_template_sched] skip sync: nil receiver/adapter/template (e_nil=%v, adapter_nil=%v, template_nil=%v)",
45+
e == nil, e != nil && e.scheduleAdapter == nil, template == nil)
4446
return
4547
}
4648
templateID := template.GetID()
4749
spaceID := template.GetSpaceID()
4850
if templateID <= 0 || spaceID <= 0 {
51+
logs.CtxWarn(ctx, "[expt_template_sched] skip sync: invalid id, space_id=%d, template_id=%d", spaceID, templateID)
4952
return
5053
}
5154

5255
bizKey := buildScheduleBizKey(spaceID, templateID)
5356
source := template.ExptSource
57+
cronActivate := template.ExptInfo != nil && template.ExptInfo.CronActivate
58+
59+
// 入口日志:先把所有判定输入打齐,便于一行定位"为什么没下发"
60+
logs.CtxInfo(ctx, "[expt_template_sched] start sync, biz_key=%s, source_type=%v, cron_activate=%v, has_scheduler=%v, scheduler=%s",
61+
bizKey,
62+
schedSourceTypeName(source),
63+
cronActivate,
64+
source != nil && source.Scheduler != nil,
65+
schedDescribeScheduler(source))
5466

5567
// 非 Evaluation 来源不接管定时调度;同时清理可能遗留的任务以避免误触发
5668
if source == nil || source.SourceType != entity.SourceType_Evaluation {
69+
logs.CtxInfo(ctx, "[expt_template_sched] non-evaluation source, will close any existing job, biz_key=%s, source_type=%v",
70+
bizKey, schedSourceTypeName(source))
5771
if err := e.scheduleAdapter.CloseJob(ctx, bizKey); err != nil {
58-
logs.CtxWarn(ctx, "[expt_template] close schedule job failed (non-evaluation source), biz_key=%s, err=%v", bizKey, err)
72+
logs.CtxWarn(ctx, "[expt_template_sched] close schedule job failed (non-evaluation source), biz_key=%s, err=%v", bizKey, err)
5973
}
6074
return
6175
}
6276

6377
// 模板未启用 cron 或 Scheduler 配置缺失/未启用 → 关闭已存在任务
64-
cronActivate := template.ExptInfo != nil && template.ExptInfo.CronActivate
6578
if !cronActivate || source.Scheduler == nil || !isSchedulerEnabled(source.Scheduler) {
79+
reason := schedDisabledReason(cronActivate, source.Scheduler)
80+
logs.CtxInfo(ctx, "[expt_template_sched] schedule disabled, will close any existing job, biz_key=%s, reason=%s",
81+
bizKey, reason)
6682
if err := e.scheduleAdapter.CloseJob(ctx, bizKey); err != nil {
67-
logs.CtxWarn(ctx, "[expt_template] close schedule job failed, biz_key=%s, err=%v", bizKey, err)
83+
logs.CtxWarn(ctx, "[expt_template_sched] close schedule job failed, biz_key=%s, reason=%s, err=%v", bizKey, reason, err)
6884
}
6985
return
7086
}
7187

7288
param, err := buildCreatePeriodicJobParam(bizKey, spaceID, templateID, source.Scheduler)
7389
if err != nil {
74-
logs.CtxError(ctx, "[expt_template] build create periodic job param failed, biz_key=%s, err=%v", bizKey, err)
90+
logs.CtxError(ctx, "[expt_template_sched] build create periodic job param failed, biz_key=%s, err=%v", bizKey, err)
7591
return
7692
}
93+
logs.CtxInfo(ctx, "[expt_template_sched] dispatch CreatePeriodicJob, biz_key=%s, crontab=%s, started_at=%v, ended_at=%v, callback=%s, payload=%s",
94+
param.BizKey, param.Crontab, param.StartedAt, param.EndedAt, param.CallbackMethod, param.CallbackPayload)
7795
if err := e.scheduleAdapter.CreatePeriodicJob(ctx, param); err != nil {
78-
logs.CtxError(ctx, "[expt_template] create periodic schedule job failed, biz_key=%s, err=%v", bizKey, err)
96+
logs.CtxError(ctx, "[expt_template_sched] create periodic schedule job failed, biz_key=%s, crontab=%s, err=%v", bizKey, param.Crontab, err)
7997
return
8098
}
81-
logs.CtxInfo(ctx, "[expt_template] schedule job synced, biz_key=%s, frequency=%s, crontab=%s",
99+
logs.CtxInfo(ctx, "[expt_template_sched] schedule job synced, biz_key=%s, frequency=%s, crontab=%s",
82100
bizKey, *source.Scheduler.Frequency, param.Crontab)
83101
}
84102

103+
// schedSourceTypeName 把 SourceType 打成可读字符串,便于日志快速定位
104+
func schedSourceTypeName(src *entity.ExptSource) string {
105+
if src == nil {
106+
return "<nil_source>"
107+
}
108+
return fmt.Sprintf("%d", src.SourceType)
109+
}
110+
111+
// schedDescribeScheduler 把 Scheduler 字段一行展开,所有可空字段都安全打印
112+
func schedDescribeScheduler(src *entity.ExptSource) string {
113+
if src == nil || src.Scheduler == nil {
114+
return "<nil_scheduler>"
115+
}
116+
s := src.Scheduler
117+
enabled := false
118+
if s.Enabled != nil {
119+
enabled = *s.Enabled
120+
}
121+
freq := ""
122+
if s.Frequency != nil {
123+
freq = *s.Frequency
124+
}
125+
var trigger, start, end int64
126+
if s.TriggerAt != nil {
127+
trigger = *s.TriggerAt
128+
}
129+
if s.StartTime != nil {
130+
start = *s.StartTime
131+
}
132+
if s.EndTime != nil {
133+
end = *s.EndTime
134+
}
135+
return fmt.Sprintf("{enabled=%v,frequency=%q,trigger_at=%d,start_time=%d,end_time=%d}",
136+
enabled, freq, trigger, start, end)
137+
}
138+
139+
// schedDisabledReason 推导本次"未下发周期任务"的具体原因,便于排查
140+
func schedDisabledReason(cronActivate bool, s *entity.ExptSchedulerDO) string {
141+
if !cronActivate {
142+
return "expt_info.cron_activate=false"
143+
}
144+
if s == nil {
145+
return "scheduler is nil (DTO 转换/落库链路没有保留 Scheduler?)"
146+
}
147+
if s.Enabled == nil || !*s.Enabled {
148+
return "scheduler.enabled=false"
149+
}
150+
if s.Frequency == nil || *s.Frequency == "" {
151+
return "scheduler.frequency is empty"
152+
}
153+
if s.TriggerAt == nil || *s.TriggerAt <= 0 {
154+
return "scheduler.trigger_at is empty"
155+
}
156+
return "unknown"
157+
}
158+
85159
// isSchedulerEnabled 判断 ExptSchedulerDO 是否启用且配置完整
86160
func isSchedulerEnabled(s *entity.ExptSchedulerDO) bool {
87161
if s == nil {

0 commit comments

Comments
 (0)