feat: trace task sources to fixed workflow activations and rounds
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
core "git.yuntuo.hk/k2safe/orbit/model"
|
||||
"git.yuntuo.hk/k2safe/orbit/platform/auth"
|
||||
"git.yuntuo.hk/k2safe/orbit/pulse/service"
|
||||
"git.yuntuo.hk/k2safe/orbit/weave/engine"
|
||||
)
|
||||
|
||||
func (s *TaskStore) GetTaskSource(ctx context.Context, t auth.Token, id core.ID) (service.TaskSourceView, error) {
|
||||
@@ -18,7 +19,12 @@ func (s *TaskStore) GetTaskSource(ctx context.Context, t auth.Token, id core.ID)
|
||||
var queue core.ID
|
||||
var owner sql.NullString
|
||||
var ownerID, gate, retry *core.ID
|
||||
err := tx.QueryRowContext(ctx, `SELECT queue_id,owner_kind,owner_id,gate_id,retry_of FROM pulse_tasks WHERE namespace_id=? AND id=?`, t.NamespaceID, id).Scan(&queue, &owner, &ownerID, &gate, &retry)
|
||||
var scheduled, activated, polled bool
|
||||
err := tx.QueryRowContext(ctx, `SELECT queue_id,owner_kind,owner_id,gate_id,retry_of,
|
||||
EXISTS(SELECT 1 FROM pulse_schedule_occurrences o WHERE o.namespace_id=t.namespace_id AND o.task_id=t.id),
|
||||
EXISTS(SELECT 1 FROM weave_activations a WHERE a.namespace_id=t.namespace_id AND a.task_id=t.id),
|
||||
EXISTS(SELECT 1 FROM weave_poll_rounds r WHERE r.namespace_id=t.namespace_id AND r.task_id=t.id)
|
||||
FROM pulse_tasks t WHERE namespace_id=? AND id=?`, t.NamespaceID, id).Scan(&queue, &owner, &ownerID, &gate, &retry, &scheduled, &activated, &polled)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return fault.NotFound
|
||||
}
|
||||
@@ -28,8 +34,22 @@ func (s *TaskStore) GetTaskSource(ctx context.Context, t auth.Token, id core.ID)
|
||||
if !p.AllowsQueue(queue) {
|
||||
return fault.NotFound
|
||||
}
|
||||
// 来源字段由创建事务固定;当前未实现的门控/所有者不能被误判为普通受理。
|
||||
if gate != nil || owner.Valid != (ownerID != nil) || owner.Valid && retry != nil {
|
||||
// 反向关联同样必须存在且种类唯一;丢失所有者不能把流程任务降级为普通受理。
|
||||
if owner.Valid != (ownerID != nil) {
|
||||
return fault.Unavailable
|
||||
}
|
||||
if owner.Valid && owner.String == engine.TaskOwnerKind {
|
||||
if gate == nil || scheduled || activated == polled {
|
||||
return fault.Unavailable
|
||||
}
|
||||
source, err := readTaskWorkflowSource(ctx, tx, t.NamespaceID, id, queue, *ownerID, *gate, activated)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out.Kind, out.Workflow = "WORKFLOW", &source
|
||||
return nil
|
||||
}
|
||||
if gate != nil || activated || polled || owner.Valid && retry != nil {
|
||||
return fault.Unavailable
|
||||
}
|
||||
if owner.Valid {
|
||||
@@ -56,11 +76,7 @@ func (s *TaskStore) GetTaskSource(ctx context.Context, t auth.Token, id core.ID)
|
||||
out.Schedule = &source
|
||||
return nil
|
||||
}
|
||||
var occurrences int
|
||||
if err := tx.QueryRowContext(ctx, `SELECT COUNT(*) FROM pulse_schedule_occurrences WHERE namespace_id=? AND task_id=?`, t.NamespaceID, id).Scan(&occurrences); err != nil {
|
||||
return err
|
||||
}
|
||||
if occurrences != 0 {
|
||||
if scheduled {
|
||||
return fault.Unavailable
|
||||
}
|
||||
if retry == nil {
|
||||
@@ -68,7 +84,10 @@ func (s *TaskStore) GetTaskSource(ctx context.Context, t auth.Token, id core.ID)
|
||||
return nil
|
||||
}
|
||||
var parent core.ID
|
||||
err = tx.QueryRowContext(ctx, `SELECT id FROM pulse_tasks WHERE namespace_id=? AND id=? AND id<>? AND queue_id=? AND owner_kind IS NULL AND owner_id IS NULL AND gate_id IS NULL AND state IN ('FAILED','CANCELLED')`, t.NamespaceID, *retry, id, queue).Scan(&parent)
|
||||
err = tx.QueryRowContext(ctx, `SELECT id FROM pulse_tasks t WHERE namespace_id=? AND id=? AND id<>? AND queue_id=? AND owner_kind IS NULL AND owner_id IS NULL AND gate_id IS NULL AND state IN ('FAILED','CANCELLED')
|
||||
AND NOT EXISTS(SELECT 1 FROM pulse_schedule_occurrences o WHERE o.namespace_id=t.namespace_id AND o.task_id=t.id)
|
||||
AND NOT EXISTS(SELECT 1 FROM weave_activations a WHERE a.namespace_id=t.namespace_id AND a.task_id=t.id)
|
||||
AND NOT EXISTS(SELECT 1 FROM weave_poll_rounds r WHERE r.namespace_id=t.namespace_id AND r.task_id=t.id)`, t.NamespaceID, *retry, id, queue).Scan(&parent)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return fault.Unavailable
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user