Files
orbit/sdk/go/task_source.go

69 lines
2.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package orbit
import (
"context"
"errors"
"time"
)
// TaskSource 只读的直接来源,不遍历整条重试链,也不授予来源资源管理权限。
type TaskSource struct {
// TaskID 本次已授权查询的任务标识。
TaskID string `json:"task_id"`
// Kind 当前支持DIRECT、MANUAL_RETRY、SCHEDULE;分别是普通受理、人工派生、计划触发。
Kind string `json:"kind"`
// RetryOf 人工重试的直接原任务,限同一命名空间及队列;其他种类省略。
RetryOf *string `json:"retry_of,omitempty"`
// Schedule 计划触发的固定来源,仅SCHEDULE返回,不包含任务模板或计划配置。
Schedule *TaskScheduleSource `json:"schedule,omitempty"`
}
// TaskScheduleSource 关联已生成任务的触发记录及当时的不可变计划版本。
type TaskScheduleSource struct {
// ScheduleID 原计划标识,不因发布新版本而变化。
ScheduleID string `json:"schedule_id"`
// ScheduleVersion 触发时使用的固定版本,JSON字符串避免精度丢失。
ScheduleVersion uint64 `json:"schedule_version,string"`
// OccurrenceID 唯一关联该任务的触发记录标识。
OccurrenceID string `json:"occurrence_id"`
// ScheduledAt 原计划时间,UTC微秒精度,不等于实际受理/执行时间。
ScheduledAt time.Time `json:"scheduled_at"`
// Decision FIRED为单点触发,COALESCED为合并触发;跳过不会产生任务。
Decision string `json:"decision"`
// CoveredUntil 合并范围的排除边界,仅COALESCED返回。
CoveredUntil *time.Time `json:"covered_until,omitempty"`
}
// GetTaskSource 查询直接来源;不会授予来源计划的读取/管理或任务执行权限。
func (c *Client) GetTaskSource(ctx context.Context, id string) (TaskSource, error) {
var out TaskSource
if !validID(id) {
return out, errors.New("invalid task id")
}
if err := c.call(ctx, "GET", "/v1/tasks/"+id+"/source", "", nil, &out); err != nil {
return TaskSource{}, err
}
if out.TaskID != id {
return TaskSource{}, errors.New("source does not match requested task")
}
valid := false
switch out.Kind {
case "DIRECT":
valid = out.RetryOf == nil && out.Schedule == nil
case "MANUAL_RETRY":
valid = out.RetryOf != nil && validID(*out.RetryOf) && *out.RetryOf != id && out.Schedule == nil
case "SCHEDULE":
s := out.Schedule
if s != nil && out.RetryOf == nil && validID(s.ScheduleID) && validID(s.OccurrenceID) && s.ScheduleVersion > 0 && validSourceTime(s.ScheduledAt) {
valid = s.Decision == "FIRED" && s.CoveredUntil == nil || s.Decision == "COALESCED" && s.CoveredUntil != nil && validSourceTime(*s.CoveredUntil) && s.CoveredUntil.After(s.ScheduledAt)
}
}
if !valid {
return TaskSource{}, errors.New("invalid or unsupported task source response")
}
return out, nil
}
func validSourceTime(t time.Time) bool {
return t.Year() >= 2000 && t.Year() <= 9998 && t.Nanosecond()%1000 == 0
}