98 lines
5.4 KiB
Go
98 lines
5.4 KiB
Go
package orbit
|
||
|
||
import (
|
||
"context"
|
||
"errors"
|
||
"net/url"
|
||
"strconv"
|
||
"strings"
|
||
"time"
|
||
"unicode/utf8"
|
||
)
|
||
|
||
// ListWorkflowsRequest 在认证命名空间内筛选实例;所有队列权限必须覆盖整个固定定义版本。
|
||
type ListWorkflowsRequest struct {
|
||
DefinitionID string // DefinitionID 可选定义身份,未传入时跨已授权定义查询。
|
||
Version string // Version 可选固定发布版本名,仅在指定定义时使用。
|
||
State string // State 可选执行状态,与暂停标志独立。
|
||
Paused *bool // Paused nil不筛选;false明确筛选未暂停实例。
|
||
BusinessKey string // BusinessKey 非空时精确匹配,包含尾部空格;空表示不筛选。
|
||
CreatedFrom *time.Time // CreatedFrom 可选创建时间下界,包含,UTC微秒精度。
|
||
CreatedBefore *time.Time // CreatedBefore 可选创建时间上界,不包含。
|
||
Limit int // Limit 默认20,上限100。
|
||
Cursor string // Cursor 服务端返回的位置,绑定命名空间、全部筛选及队列权限范围。
|
||
}
|
||
|
||
// Summary 仅返回实例元数据,不聚合业务输入输出、定义或策略快照。
|
||
type WorkflowSummary struct {
|
||
ID string `json:"id"` // ID 实例身份。
|
||
NamespaceID string `json:"namespace_id"` // NamespaceID 授权及数据隔离范围。
|
||
DefinitionID string `json:"definition_id"` // DefinitionID 稳定定义身份。
|
||
DefinitionVersionID string `json:"definition_version_id"` // DefinitionVersionID 固定版本记录身份。
|
||
Version string `json:"version"` // Version 启动时固定的发布版本名。
|
||
State string `json:"state"` // State 执行状态,受理不代表业务成功。
|
||
Revision uint64 `json:"revision,string"` // Revision 实例并发版本。
|
||
Paused bool `json:"paused"` // Paused 独立暂停标志,不表示在途工作已停止。
|
||
ControlRevision uint64 `json:"control_revision,string"` // ControlRevision 控制操作并发版本。
|
||
BusinessKey string `json:"business_key"` // BusinessKey 原始追踪键。
|
||
DeadlineAt time.Time `json:"deadline_at"` // DeadlineAt 数据库时间确定的固定总截止。
|
||
CancelRequestedAt *time.Time `json:"cancel_requested_at,omitempty"` // CancelRequestedAt 已保存的取消意图时间。
|
||
StopKind *string `json:"stop_kind,omitempty"` // StopKind 首次停止原因CANCEL或FAILURE;核查不会清除。
|
||
StopRequestedAt *time.Time `json:"stop_requested_at,omitempty"` // StopRequestedAt 首次停止意图时间,后续操作不会延长。
|
||
CompletedAt *time.Time `json:"completed_at,omitempty"` // CompletedAt 终结时间,非终态为空。
|
||
CreatedAt time.Time `json:"created_at"` // CreatedAt UTC受理时间。
|
||
UpdatedAt time.Time `json:"updated_at"` // UpdatedAt 最近状态更新时间。
|
||
}
|
||
|
||
type WorkflowPage struct {
|
||
Items []WorkflowSummary `json:"items"` // Items 按创建时间及ID倒序的授权摘要;空列表为[]。
|
||
NextCursor string `json:"next_cursor,omitempty"` // NextCursor 沿相同筛选与权限继续使用,空表示本次无下一页。
|
||
}
|
||
|
||
// ListWorkflows 查询当前凭据可读取的流程摘要;分页筛选和队列权限必须保持一致。
|
||
func (c *Client) ListWorkflows(ctx context.Context, in ListWorkflowsRequest) (WorkflowPage, error) {
|
||
var out WorkflowPage
|
||
if in.Limit < 0 || in.Limit > 100 || len(in.Cursor) > 1024 || in.DefinitionID != "" && !validID(in.DefinitionID) || in.Version != "" && (in.DefinitionID == "" || !workflowVersionName(in.Version)) {
|
||
return out, errors.New("invalid workflow query definition, version or page")
|
||
}
|
||
switch in.State {
|
||
case "", "RUNNING", "WAITING", "CANCELLING", "NEEDS_REVIEW", "SUCCEEDED", "FAILED", "CANCELLED":
|
||
default:
|
||
return out, errors.New("invalid workflow state")
|
||
}
|
||
if !utf8.ValidString(in.BusinessKey) || utf8.RuneCountInString(in.BusinessKey) > 191 || strings.ContainsRune(in.BusinessKey, 0) {
|
||
return out, errors.New("invalid workflow business key filter")
|
||
}
|
||
q := url.Values{}
|
||
for name, v := range map[string]string{"definition_id": in.DefinitionID, "version": in.Version, "state": in.State, "business_key": in.BusinessKey, "cursor": in.Cursor} {
|
||
if v != "" {
|
||
q.Set(name, v)
|
||
}
|
||
}
|
||
if in.Paused != nil {
|
||
q.Set("paused", strconv.FormatBool(*in.Paused))
|
||
}
|
||
if in.Limit != 0 {
|
||
q.Set("limit", strconv.Itoa(in.Limit))
|
||
}
|
||
for name, field := range map[string]*time.Time{"created_from": in.CreatedFrom, "created_before": in.CreatedBefore} {
|
||
if field == nil {
|
||
continue
|
||
}
|
||
v := field.UTC()
|
||
if v.Year() < 2000 || v.Year() > 9998 || v.Nanosecond()%1000 != 0 {
|
||
return out, errors.New("invalid workflow creation time bound")
|
||
}
|
||
q.Set(name, v.Format(time.RFC3339Nano))
|
||
}
|
||
if in.CreatedFrom != nil && in.CreatedBefore != nil && !in.CreatedFrom.Before(*in.CreatedBefore) {
|
||
return out, errors.New("created_from must be before created_before")
|
||
}
|
||
path := "/v1/workflows"
|
||
if len(q) > 0 {
|
||
path += "?" + q.Encode()
|
||
}
|
||
err := c.call(ctx, "GET", path, "", nil, &out)
|
||
return out, err
|
||
}
|