feat: observe workflow inbox backlog
This commit is contained in:
@@ -25,6 +25,10 @@ type OperationalSnapshot struct {
|
||||
WorkflowStates map[string]uint64
|
||||
// WorkflowOldestAgeSeconds 是未终结流程中最早 updated_at 的年龄。
|
||||
WorkflowOldestAgeSeconds float64
|
||||
// InboxStates 是 Weave 内部事件按状态的有界计数。
|
||||
InboxStates map[string]uint64
|
||||
// InboxOldestAgeSeconds 是待消费内部事件中最早 available_at 的年龄。
|
||||
InboxOldestAgeSeconds float64
|
||||
// Truncated 表示至少一个状态达到有界采样上限。
|
||||
Truncated bool
|
||||
// RecentEvents 是固定事件类别在最近窗口内的有界数量。
|
||||
@@ -43,6 +47,7 @@ var (
|
||||
operationalTaskStates = []string{"WAITING", "LEASED", "RUNNING", "NEEDS_REVIEW", "SUCCEEDED", "FAILED", "CANCELLED"}
|
||||
operationalDeliveryStates = []string{"PENDING", "LEASED", "ACKED", "EXPIRED"}
|
||||
operationalWorkflowStates = []string{"RUNNING", "WAITING", "CANCELLING", "NEEDS_REVIEW", "SUCCEEDED", "FAILED", "CANCELLED"}
|
||||
operationalInboxStates = []string{"PENDING", "LEASED", "PROCESSED", "QUARANTINED"}
|
||||
operationalEventTypes = []string{"task.accepted", "task.started", "task.succeeded", "task.failed", "task.needs_review", "task.requeued", "workflow.started", "workflow.advanced", "workflow.recovered", "workflow.blocked", "workflow.stopped"}
|
||||
)
|
||||
|
||||
@@ -68,10 +73,18 @@ func ReadOperationalSnapshot(ctx context.Context, db *sql.DB) (OperationalSnapsh
|
||||
if err != nil {
|
||||
return OperationalSnapshot{}, err
|
||||
}
|
||||
inbox, inboxTruncated, err := boundedStateCounts(ctx, db, "weave_inbox", "ix_inbox_due", operationalInboxStates)
|
||||
if err != nil {
|
||||
return OperationalSnapshot{}, err
|
||||
}
|
||||
taskAge, err := oldestAge(ctx, db, "pulse_tasks", "ix_task_observe_state_available", []string{"WAITING", "LEASED", "RUNNING", "NEEDS_REVIEW"}, "available_at", now)
|
||||
if err != nil {
|
||||
return OperationalSnapshot{}, err
|
||||
}
|
||||
inboxAge, err := oldestAge(ctx, db, "weave_inbox", "ix_inbox_due", []string{"PENDING", "LEASED"}, "available_at", now)
|
||||
if err != nil {
|
||||
return OperationalSnapshot{}, err
|
||||
}
|
||||
deliveryAge, err := oldestAge(ctx, db, "orbit_deliveries", "ix_delivery_observe_state_available", []string{"PENDING", "LEASED"}, "available_at", now)
|
||||
if err != nil {
|
||||
return OperationalSnapshot{}, err
|
||||
@@ -96,10 +109,11 @@ func ReadOperationalSnapshot(ctx context.Context, db *sql.DB) (OperationalSnapsh
|
||||
TaskStates: tasks, TaskOldestAgeSeconds: taskAge,
|
||||
DeliveryStates: deliveries, DeliveryOldestAgeSeconds: deliveryAge,
|
||||
WorkflowStates: workflows, WorkflowOldestAgeSeconds: workflowAge,
|
||||
InboxStates: inbox, InboxOldestAgeSeconds: inboxAge,
|
||||
RecentEvents: events,
|
||||
TaskTerminalLatencySeconds: taskLatency.average, TaskTerminalLatencyMaxSeconds: taskLatency.maximum,
|
||||
WorkflowTerminalLatencySeconds: workflowLatency.average, WorkflowTerminalLatencyMaxSeconds: workflowLatency.maximum,
|
||||
Truncated: taskTruncated || deliveryTruncated || workflowTruncated || eventTruncated || taskLatency.truncated || workflowLatency.truncated,
|
||||
Truncated: taskTruncated || deliveryTruncated || workflowTruncated || inboxTruncated || eventTruncated || taskLatency.truncated || workflowLatency.truncated,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ func TestIntegrationOperationalSnapshot(t *testing.T) {
|
||||
if got := snapshot.RecentEvents["task.accepted"]; got < 1 {
|
||||
t.Fatalf("accepted event was not observed: %#v", snapshot.RecentEvents)
|
||||
}
|
||||
if snapshot.TaskOldestAgeSeconds < 0 || snapshot.DeliveryOldestAgeSeconds < 0 || snapshot.WorkflowOldestAgeSeconds < 0 {
|
||||
if snapshot.TaskOldestAgeSeconds < 0 || snapshot.DeliveryOldestAgeSeconds < 0 || snapshot.WorkflowOldestAgeSeconds < 0 || snapshot.InboxOldestAgeSeconds < 0 {
|
||||
t.Fatalf("negative age in snapshot: %#v", snapshot)
|
||||
}
|
||||
for _, state := range []string{"WAITING", "LEASED", "RUNNING", "NEEDS_REVIEW", "SUCCEEDED", "FAILED", "CANCELLED"} {
|
||||
@@ -84,6 +84,11 @@ func TestIntegrationOperationalSnapshot(t *testing.T) {
|
||||
if _, ok := snapshot.WorkflowStates["RUNNING"]; !ok {
|
||||
t.Fatal("missing running workflow state")
|
||||
}
|
||||
for _, state := range []string{"PENDING", "LEASED", "PROCESSED", "QUARANTINED"} {
|
||||
if _, ok := snapshot.InboxStates[state]; !ok {
|
||||
t.Fatalf("missing fixed inbox state %q", state)
|
||||
}
|
||||
}
|
||||
f.exec("UPDATE pulse_tasks SET state='SUCCEEDED', completed_at=UTC_TIMESTAMP(6), updated_at=UTC_TIMESTAMP(6), revision=revision+1 WHERE namespace_id=? AND id=?", f.resources.NamespaceID, task.ID)
|
||||
completed, err := ReadOperationalSnapshot(ctx, db)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user