feat: support durable task cancellation without foreign keys
This commit is contained in:
@@ -97,6 +97,8 @@ func TestWorkerPublishedContract(t *testing.T) {
|
||||
secret := strings.Repeat("A", 43)
|
||||
ref := worker.AttemptRef{TaskID: id, AttemptID: id, Epoch: 1, LeaseSecret: secret}
|
||||
hello := worker.ConnectInput{InstanceID: id, InstanceSecret: secret, QueueID: id, Capacity: 1, Capabilities: []worker.Capability{{Handler: "text.normalize", HandlerVersion: "v1", PayloadVersion: "v1"}}}
|
||||
helloWithCancellation := hello
|
||||
helloWithCancellation.CancellationNotifications = true
|
||||
cases := []struct {
|
||||
kind string
|
||||
body any
|
||||
@@ -108,6 +110,8 @@ func TestWorkerPublishedContract(t *testing.T) {
|
||||
{"task.finish", worker.FinishInput{Ref: ref, Outcome: "FAILED", ErrorCode: "OBJECT_REJECTED", Result: json.RawMessage(`{}`)}},
|
||||
{"task.finish", worker.FinishInput{Ref: ref, Outcome: "UNKNOWN", ErrorCode: "LEASE_LOST", Result: json.RawMessage(`{}`)}},
|
||||
{"task.finish", worker.FinishInput{Ref: ref, Outcome: "FAILED", Retryable: true, ErrorCode: "TEMPORARY_REJECTION", Result: json.RawMessage(`{}`)}},
|
||||
{"task.finish", worker.FinishInput{Ref: ref, Outcome: "CANCELLED", ErrorCode: "CANCEL_CONFIRMED", Result: json.RawMessage(`{}`)}},
|
||||
{"worker.hello", helloWithCancellation},
|
||||
}
|
||||
var valid [][]byte
|
||||
for _, tc := range cases {
|
||||
@@ -147,6 +151,7 @@ func TestWorkerPublishedContract(t *testing.T) {
|
||||
{"failure_missing_code", strings.Replace(string(valid[6]), `,"error_code":"OBJECT_REJECTED"`, ``, 1)},
|
||||
{"success_with_code", strings.Replace(string(valid[6]), `"FAILED"`, `"SUCCEEDED"`, 1)},
|
||||
{"unknown_retry_flag", strings.Replace(string(valid[8]), `"FAILED"`, `"UNKNOWN"`, 1)},
|
||||
{"cancelled_retry_flag", strings.Replace(string(valid[8]), `"FAILED"`, `"CANCELLED"`, 1)},
|
||||
}
|
||||
for _, tc := range invalid {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
@@ -180,7 +185,7 @@ func TestWorkerPublishedContract(t *testing.T) {
|
||||
|
||||
now := time.Date(2026, 9, 17, 8, 0, 0, 0, time.UTC)
|
||||
welcome := worker.Welcome{SessionID: id, Epoch: 1, ServerTime: now, ExpiresAt: now.Add(45 * time.Second), LeaseDurationMS: 30000}
|
||||
lease := worker.LeaseStatus{Active: true, State: pulse.AttemptRunning, LeaseUntil: now.Add(30 * time.Second), ServerTime: now}
|
||||
lease := worker.LeaseStatus{Active: true, State: pulse.AttemptRunning, LeaseUntil: now.Add(30 * time.Second), ServerTime: now, CancelRequestedAt: &now}
|
||||
receipt := worker.Receipt{Operation: "start", TaskState: pulse.TaskRunning, AttemptState: pulse.AttemptRunning, TaskRevision: 3, LeaseUntil: lease.LeaseUntil, Disposition: "APPLIED"}
|
||||
task := service.TaskView{ID: id, NamespaceID: id, QueueID: id, State: pulse.TaskLeased, Revision: 2, Handler: "text.normalize", HandlerVersion: "v1", PayloadVersion: "v1", Payload: json.RawMessage(`{}`), AvailableAt: now, DeadlineAt: now.Add(time.Hour), RecoverySafety: pulse.RecoveryReconcileOnly, Retry: pulse.RetryPolicy{MaxAttempts: 1, AttemptTimeoutMS: 30000}, AttemptCount: 1, CreatedAt: now, UpdatedAt: now}
|
||||
assignment := worker.Assignment{Task: task, AttemptID: id, Epoch: 1, LeaseSecret: secret, LeaseUntil: lease.LeaseUntil, ServerTime: now}
|
||||
@@ -190,10 +195,11 @@ func TestWorkerPublishedContract(t *testing.T) {
|
||||
}{
|
||||
{"worker.welcome", welcome}, {"ack", welcome}, {"ack", lease},
|
||||
{"ack", worker.CommandResult{Receipt: receipt, Lease: lease, Deduplicated: true}}, {"task.assign", assignment},
|
||||
{"task.cancel", worker.Cancellation{TaskID: id, AttemptID: id, Epoch: 1, RequestedAt: now}},
|
||||
} {
|
||||
raw, _ := jsonwire.Marshal(tc.body)
|
||||
f := workerFrame{Version: "1", Type: tc.kind, MessageID: id, SessionID: id, ReplyTo: id, Body: raw}
|
||||
if tc.kind == "task.assign" {
|
||||
if tc.kind == "task.assign" || tc.kind == "task.cancel" {
|
||||
f.ReplyTo = ""
|
||||
}
|
||||
frame, _ := jsonwire.Marshal(f)
|
||||
|
||||
Reference in New Issue
Block a user