docs: consolidate runnable examples and publish v0.1.1 guides

This commit is contained in:
2026-09-24 21:27:25 +08:00
parent e29dec717f
commit 81e56bd633
124 changed files with 1430 additions and 281 deletions

View File

@@ -0,0 +1,129 @@
// delayed-task 演示数据库计时的相对延迟、原键核对和实际 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 json.Unmarshal(raw, &credentials) != nil {
return errors.New("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
}
op, err := orbit.NewWorkerMessageID()
if err != nil {
return err
}
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
in := orbit.SubmitTaskRequest{QueueID: queue, Handler: "object.delayed." + op, HandlerVersion: "v1", PayloadVersion: "v1", Payload: json.RawMessage(`{"object_ref":"examples/input","sequence":9007199254740993}`), DelayMS: 1500, TaskTimeoutMS: 15000, Retry: orbit.RetryPolicy{MaxAttempts: 1, AttemptTimeoutMS: 5000}}
accepted, err := client.SubmitTask(ctx, op, in)
if err != nil {
return err
}
// 先输出任务身份,后续失败可据此核对;不输出凭据或任意业务正文。
fmt.Printf("task=%s delay_ms=%d\n", accepted.Task.ID, in.DelayMS)
if !accepted.Task.AvailableAt.Equal(accepted.Task.CreatedAt.Add(1500 * time.Millisecond)) {
return errors.New("delay was not based on database acceptance")
}
w, err := orbit.NewWorker(client, orbit.WorkerOptions{QueueID: queue, Capacity: 1, ShutdownTimeout: 5 * time.Second, Handlers: []orbit.WorkerHandler{{Capability: orbit.WorkerCapability{Handler: in.Handler, HandlerVersion: "v1", PayloadVersion: "v1"}, Handle: func(ctx context.Context, e orbit.WorkerExecution) (json.RawMessage, error) {
if err := ctx.Err(); err != nil {
return nil, err
}
// 无外部副作用的示例处理器,保持精确数字文本。
return e.Task.Payload, nil
}}}})
if err != nil {
return err
}
work, stop := context.WithCancel(ctx)
done := make(chan error, 1)
go func() { done <- w.Run(work) }()
waited := false
defer func() {
stop()
if !waited {
<-done
}
}()
for {
current, err := client.GetTask(ctx, accepted.Task.ID)
if err != nil {
return err
}
if current.State == orbit.TaskSucceeded {
history, err := client.ListTaskAttempts(ctx, current.ID, orbit.HistoryPageRequest{})
if err != nil {
return err
}
if len(history.Items) != 1 || history.Items[0].AuthorizedAt == nil || history.Items[0].CreatedAt.Before(accepted.Task.AvailableAt) || history.Items[0].AuthorizedAt.Before(accepted.Task.AvailableAt) {
return errors.New("execution preceded the saved release time")
}
break
}
if current.State == orbit.TaskFailed || current.State == orbit.TaskNeedsReview || current.State == orbit.TaskCancelled {
return fmt.Errorf("task requires attention: %s", current.State)
}
select {
case err := <-done:
waited = true
return fmt.Errorf("Worker stopped before completion: %v", err)
case <-ctx.Done():
return ctx.Err()
case <-time.After(100 * time.Millisecond):
}
}
duplicate, err := client.SubmitTask(ctx, op, in)
if err != nil {
return err
}
if !duplicate.Deduplicated || duplicate.Task.ID != accepted.Task.ID || !duplicate.Task.AvailableAt.Equal(accepted.Task.AvailableAt) {
return errors.New("replay changed the original delayed task")
}
stop()
err = <-done
waited = true
if err != nil {
return err
}
stats := w.Stats()
if stats.Started != 1 || stats.ReportsConfirmed != 1 || stats.Running != 0 {
return errors.New("Worker did not confirm and drain")
}
fmt.Println("state=SUCCEEDED attempts=1 no_early_start=true original_receipt=true worker_drained=true")
return nil
}