// task-query 演示业务键精确匹配、创建时间边界和任务摘要分页,不启动Worker。 package main import ( "context" "encoding/json" "errors" "fmt" "os" "time" orbit "git.yuntuo.hk/k2safe/orbit/sdk/go" ) func main() { if err := run(); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } } func run() error { token, queue := os.Getenv("ORBIT_TOKEN"), os.Getenv("ORBIT_QUEUE_ID") if path := os.Getenv("ORBIT_CREDENTIALS_FILE"); path != "" { raw, err := os.ReadFile(path) if err != nil { return fmt.Errorf("read private credentials: %w", err) } var credentials struct { Token string `json:"token"` QueueID string `json:"queue_id"` } if err := json.Unmarshal(raw, &credentials); err != nil { return fmt.Errorf("invalid credentials file") } if token == "" { token = credentials.Token } if queue == "" { queue = credentials.QueueID } } client, err := orbit.NewClient(os.Getenv("ORBIT_URL"), orbit.Options{Token: token}) if err != nil { return err } if queue == "" { return fmt.Errorf("ORBIT_QUEUE_ID is required") } ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) defer cancel() op, err := orbit.NewWorkerMessageID() if err != nil { return err } businessKey := "对象 /+% é " + op + " " var tasks []orbit.Task for i, key := range []string{businessKey, businessKey, businessKey[:len(businessKey)-1]} { payload := json.RawMessage(`{"object_ref":"examples/input","format":"text"}`) if i == 1 { payload = json.RawMessage(`{"object_ref":"examples/input","format":"json"}`) } out, err := client.SubmitTask(ctx, fmt.Sprintf("query-%s-%d", op, i), orbit.SubmitTaskRequest{QueueID: queue, Handler: "query." + op, HandlerVersion: "v1", PayloadVersion: "v1", Payload: payload, BusinessKey: key, TaskTimeoutMS: 60000}) if err != nil { return err } tasks = append(tasks, out.Task) } // 改参数使用新身份与相同关联键,读取旧任务确认原输入仍保留。 for _, task := range tasks[:2] { current, err := client.GetTask(ctx, task.ID) if err != nil { return err } if string(current.Payload) != string(task.Payload) { return errors.New("new linked submission changed existing input") } } if tasks[0].ID == tasks[1].ID || string(tasks[0].Payload) == string(tasks[1].Payload) { return errors.New("parameter change did not create an independent task") } from, before := tasks[0].CreatedAt, tasks[2].CreatedAt.Add(time.Microsecond) query := orbit.ListTasksRequest{QueueID: queue, State: orbit.TaskWaiting, BusinessKey: businessKey, CreatedFrom: &from, CreatedBefore: &before, Limit: 1} matched, pages := 0, 0 for { page, err := client.ListTasks(ctx, query) if err != nil { return err } pages++ for _, task := range page.Items { if task.BusinessKey != businessKey { return errors.New("business key was not exact") } matched++ } if page.NextCursor == "" { break } query.Cursor = page.NextCursor } if matched != 2 || pages != 2 { return errors.New("unexpected filtered pages") } query.Cursor = "" end := tasks[1].CreatedAt query.CreatedBefore = &end bounded, err := client.ListTasks(ctx, query) if err != nil { return err } if len(bounded.Items) != 1 || bounded.Items[0].ID != tasks[0].ID { return errors.New("exclusive time boundary failed") } for i, task := range tasks { if _, err := client.CancelTask(ctx, task.ID, fmt.Sprintf("query-cancel-%s-%d", op, i), orbit.CancelTaskRequest{ExpectedRevision: task.Revision, Reason: "complete query example"}); err != nil { return err } } fmt.Printf("matched=%d pages=%d before_excluded=true original_payload_preserved=true cancelled=%d\n", matched, pages, len(tasks)) return nil }