feat: persist workflow signals and arbitrate poll completion
This commit is contained in:
@@ -14,7 +14,7 @@ import (
|
||||
// workflowCheckpoint 是待续表中版本化的内部唤醒身份;不保存内存执行栈或新的业务预算。
|
||||
type workflowCheckpoint struct {
|
||||
SchemaVersion uint32 `json:"schema_version"` // SchemaVersion 当前结构版本为1,未知版本禁止推进。
|
||||
Kind string `json:"kind"` // Kind 为ROOT、TIMER或POLL,决定实际权威记录的读取方式。
|
||||
Kind string `json:"kind"` // Kind 为ROOT、TIMER、SIGNAL或POLL,决定实际权威记录的读取方式。
|
||||
ActivationID *core.ID `json:"activation_id,omitempty"` // ActivationID 固定等待激活;ROOT不使用该字段。
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ func saveWorkflowClock(ctx context.Context, tx *sql.Tx, g *workflowGraph, row *w
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if row.view.ActivationID == nil || kind != "TIMER" && kind != "POLL" {
|
||||
if row.view.ActivationID == nil || kind != "TIMER" && kind != "POLL" && kind != "SIGNAL" {
|
||||
return errors.New("workflow clock identity invalid")
|
||||
}
|
||||
raw, err := json.Marshal(workflowCheckpoint{1, kind, row.view.ActivationID})
|
||||
@@ -60,8 +60,24 @@ func (r *WorkflowRuntime) advanceClock(ctx context.Context, tx *sql.Tx, g *workf
|
||||
return false, err
|
||||
}
|
||||
if checkpoint.Kind == "POLL" {
|
||||
node, _ := g.program.Step(row.view.Key)
|
||||
if node.Poll.FinalSignal != nil {
|
||||
handled, changed, reason, err := r.driveWorkflowSignal(ctx, tx, g, row, c, nil, allow, now)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if handled {
|
||||
if changed && reason != "" {
|
||||
return true, r.audit(ctx, tx, g, c.id, reason, now)
|
||||
}
|
||||
return changed, nil
|
||||
}
|
||||
}
|
||||
return r.advancePoll(ctx, tx, g, row, c, activated, allow, now)
|
||||
}
|
||||
if checkpoint.Kind == "SIGNAL" {
|
||||
return r.advanceSignalClock(ctx, tx, g, row, c, allow, now)
|
||||
}
|
||||
if checkpoint.Kind != "TIMER" || row.view.State != weave.StepWaiting {
|
||||
return false, errors.New("workflow timer state invalid")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user