feat(monitoring): scope authorization-failure cancellation to platform across accounts
When a monitor task's final account hits human verification or an authorization failure, cancel the remaining queued desktop/monitoring tasks for the whole platform instead of only the same account. Follow-up tasks are now marked skipped/aborted (not failed) with a platform_human_verification / platform_authorization_unavailable reason and a user-facing cancellation message, and emit task_canceled lifecycle events for monitor kinds. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2683,7 +2683,7 @@ func (s *MonitoringCallbackService) completeLinkedDesktopMonitorTask(
|
||||
|
||||
publishDesktopTaskLifecycleEvent(ctx, s.rabbitMQ, s.logger, finalizedTask, "task_completed")
|
||||
for _, failedTask := range bulkFailure.Tasks {
|
||||
publishDesktopTaskLifecycleEvent(ctx, s.rabbitMQ, s.logger, failedTask, "task_completed")
|
||||
publishDesktopTaskLifecycleEvent(ctx, s.rabbitMQ, s.logger, failedTask, desktopAuthorizationFollowupEventType(failedTask))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -3260,13 +3260,6 @@ func (s *MonitoringCallbackService) failRemainingMonitoringTasksForAuthorization
|
||||
runtimeError := buildDesktopMonitorTaskErrorValue(task, req)
|
||||
runtimeError["blocked_by_authorization_failure_task_id"] = task.ID
|
||||
runtimeError["blocked_by_authorization_failure_platform"] = task.AIPlatformID
|
||||
requestPayloadJSON, err := json.Marshal(map[string]any{
|
||||
"runtime_error": runtimeError,
|
||||
"blocked_by_authorization_failure": true,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, response.ErrInternal(50041, "task_payload_encode_failed", "failed to encode monitoring authorization failure payload")
|
||||
}
|
||||
|
||||
message := strings.TrimSpace(optionalStringValue(req.ErrorMessage))
|
||||
if message == "" {
|
||||
@@ -3275,6 +3268,18 @@ func (s *MonitoringCallbackService) failRemainingMonitoringTasksForAuthorization
|
||||
if message == "" {
|
||||
message = "登录态已失效,任务未执行。"
|
||||
}
|
||||
skipReason, cancellationMessage := authorizationFailureFollowupCancellation(disposition.Code, message)
|
||||
runtimeError["canceled"] = true
|
||||
runtimeError["cancellation_reason"] = skipReason
|
||||
runtimeError["source_authorization_failure_message"] = message
|
||||
runtimeError["message"] = cancellationMessage
|
||||
requestPayloadJSON, err := json.Marshal(map[string]any{
|
||||
"runtime_error": runtimeError,
|
||||
"blocked_by_authorization_failure": true,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, response.ErrInternal(50041, "task_payload_encode_failed", "failed to encode monitoring authorization cancellation payload")
|
||||
}
|
||||
executionOwner := strings.TrimSpace(task.ExecutionOwner)
|
||||
if executionOwner == "" {
|
||||
executionOwner = "legacy"
|
||||
@@ -3282,28 +3287,28 @@ func (s *MonitoringCallbackService) failRemainingMonitoringTasksForAuthorization
|
||||
|
||||
tag, err := tx.Exec(ctx, `
|
||||
UPDATE monitoring_collect_tasks
|
||||
SET status = 'failed',
|
||||
SET status = 'skipped',
|
||||
lease_token_hash = NULL,
|
||||
leased_to_executor = NULL,
|
||||
leased_at = NULL,
|
||||
lease_expires_at = NULL,
|
||||
callback_received_at = NOW(),
|
||||
completed_at = $7,
|
||||
skip_reason = NULL,
|
||||
error_message = $8,
|
||||
skip_reason = $8,
|
||||
error_message = $9,
|
||||
request_payload_json = (
|
||||
CASE
|
||||
WHEN request_payload_json IS NULL OR jsonb_typeof(request_payload_json) <> 'object'
|
||||
THEN '{}'::jsonb
|
||||
ELSE request_payload_json
|
||||
END
|
||||
) || $9::jsonb,
|
||||
) || $10::jsonb,
|
||||
updated_at = NOW()
|
||||
WHERE tenant_id = $1
|
||||
AND collector_type = $2
|
||||
AND business_date = $3::date
|
||||
AND ai_platform_id = $4
|
||||
AND COALESCE(execution_owner, 'legacy') = $10
|
||||
AND COALESCE(execution_owner, 'legacy') = $11
|
||||
AND id <> $5
|
||||
AND status IN ('pending', 'leased', 'expired')
|
||||
AND callback_received_at IS NULL
|
||||
@@ -3311,9 +3316,9 @@ func (s *MonitoringCallbackService) failRemainingMonitoringTasksForAuthorization
|
||||
target_client_id::text = $6
|
||||
OR leased_to_executor = $6
|
||||
)
|
||||
`, task.TenantID, task.CollectorType, task.BusinessDate.Format("2006-01-02"), task.AIPlatformID, task.ID, targetClientID, completedAt, message, requestPayloadJSON, executionOwner)
|
||||
`, task.TenantID, task.CollectorType, task.BusinessDate.Format("2006-01-02"), task.AIPlatformID, task.ID, targetClientID, completedAt, skipReason, cancellationMessage, requestPayloadJSON, executionOwner)
|
||||
if err != nil {
|
||||
return 0, response.ErrInternal(50041, "task_update_failed", "failed to fail remaining monitoring tasks after authorization failure")
|
||||
return 0, response.ErrInternal(50041, "task_update_failed", "failed to skip remaining monitoring tasks after authorization failure")
|
||||
}
|
||||
return tag.RowsAffected(), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user