feat: add durable schedule management and multi-node crash recovery

This commit is contained in:
2026-09-17 16:28:58 +08:00
parent d65cf96ea7
commit 6805506450
43 changed files with 2952 additions and 29 deletions

View File

@@ -19,11 +19,11 @@ type Occurrence struct {
ScheduledAt time.Time `db:"scheduled_at"`
// Decision 触发处理决定:已触发、已跳过或已合并。
Decision string `db:"decision"`
// TaskID 关联的 Pulse 任务标识;可为空,表示尚未设置该关联或值。
// TaskID 已触发或合并生成的 Pulse 任务标识;跳过时为空。
TaskID *core.ID `db:"task_id"`
// CoveredUntil 合并触发覆盖的结束边界;没有合并范围时为空。
// CoveredUntil 合并或跳过范围的排除边界;单点处理时为空。
CoveredUntil *time.Time `db:"covered_until"`
// Reason 操作原因或处理说明,需要保留审计信息;可为空,表示尚未设置该关联或值。
// Reason 稳定处理分类;新调度器始终写入,旧人工记录可为空。
Reason *string `db:"reason"`
}

View File

@@ -13,11 +13,17 @@ type Schedule struct {
core.Record
// Name 可读名称,唯一性范围由对应数据表约束。
Name string `db:"name"`
// QueueID 计划终身绑定的队列;旧结构人工行可为空,不允许参与扫描。
QueueID *core.ID `db:"queue_id"`
// ProcessingVersion 当前积压处理所用版本;发布新版本不覆盖旧进度。
ProcessingVersion uint64 `db:"processing_version"`
// CheckAt 下次允许扫描的 UTC 时间;为空表示当前没有扫描工作。
CheckAt *time.Time `db:"check_at"`
// CurrentVersion 当前生效的计划版本号,发布时与版本记录原子更新。
CurrentVersion uint64 `db:"current_version"`
// Paused 暂停标记;停止新的受控工作,不表示在途请求已停止。
Paused bool `db:"paused"`
// NextFireAt 下一计划触发时间;没有后续触发时为空。
// NextFireAt 下一原计划触发时间;版本刚切换尚待计算或已经结束时为空,需结合 CheckAt 判断。
NextFireAt *time.Time `db:"next_fire_at"`
}

View File

@@ -27,8 +27,12 @@ type ScheduleVersion struct {
MisfirePolicy string `db:"misfire_policy"`
// OverlapPolicy 上次未完成时的策略:并行、串行或跳过。
OverlapPolicy string `db:"overlap_policy"`
// CatchupLimit 单次漏跑补偿上限;补跑策略必须配置正数。
// CatchupLimit 每批生成任务数量上限,所有策略均要求 1–100。
CatchupLimit uint32 `db:"catchup_limit"`
// CatchupWindowMS 未处理触发点最多保留的毫秒数,过旧范围记录跳过。
CatchupWindowMS uint64 `db:"catchup_window_ms"`
// GraceMS 正常派发允许延迟的毫秒数,超出后按漏跑策略处理。
GraceMS uint64 `db:"grace_ms"`
}
func (ScheduleVersion) TableName() string { return "pulse_schedule_versions" }