feat(volces): 接入任务兼容查询与上游取消

This commit is contained in:
2026-07-22 00:25:22 +08:00
parent ddd68cfebd
commit d7951cfdd2
11 changed files with 885 additions and 55 deletions
+34
View File
@@ -526,6 +526,20 @@ candidatesLoop:
candidateBody := preprocessing.Body
candidatePricing := pricingByCandidate[pricingCandidateKey(candidate)]
response, err := s.runCandidate(ctx, task, user, candidateBody, preprocessing.Log, candidate, candidatePricing, nextAttemptNo, onDelta, responseExecution, singleSourceProtected, runnerPolicy.CacheAffinityPolicy, cacheAffinityKeys.Record)
if err != nil && isVolcesRemoteTaskCancellation(candidate, err) {
cancelled, changed, cancelErr := s.store.CancelSubmittedTask(ctx, task.ID, task.ExecutionToken, "任务已由火山引擎取消")
if cancelErr != nil {
return Result{}, cancelErr
}
if changed {
// CancelSubmittedTask atomically transfers any reservation to the release Outbox.
walletReservationFinalized = true
if emitErr := s.emit(ctx, task.ID, "task.cancelled", "cancelled", "cancelled", 1, "任务已由火山引擎取消", map[string]any{"taskId": task.ID, "reason": "upstream_cancelled"}, isSimulation(task, candidate)); emitErr != nil {
return Result{}, emitErr
}
return Result{Task: cancelled, Output: cancelled.Result}, nil
}
}
if err == nil {
attemptNo = nextAttemptNo
var billings []any
@@ -592,6 +606,13 @@ candidatesLoop:
ResponseDurationMS: record.ResponseDurationMS,
})
if finishErr != nil {
if errors.Is(finishErr, store.ErrTaskExecutionLeaseLost) {
latest, latestErr := s.store.GetTask(ctx, task.ID)
if latestErr == nil && latest.Status == "cancelled" {
walletReservationFinalized = true
return Result{Task: latest, Output: latest.Result}, nil
}
}
return Result{}, finishErr
}
walletReservationFinalized = true
@@ -965,6 +986,12 @@ func (s *Service) runCandidate(ctx context.Context, task store.GatewayTask, user
}
return s.store.SetTaskRemoteTask(context.WithoutCancel(ctx), task.ID, task.ExecutionToken, attemptID, remoteTaskID, payload)
},
OnRemoteTaskPolled: func(remoteTaskID string, payload map[string]any) error {
if strings.TrimSpace(remoteTaskID) == "" {
return nil
}
return s.store.SetTaskRemoteTask(context.WithoutCancel(ctx), task.ID, task.ExecutionToken, attemptID, remoteTaskID, payload)
},
Stream: boolFromMap(providerBody, "stream"),
StreamDelta: onDelta,
UpstreamProtocol: candidate.ResponseProtocol,
@@ -1199,12 +1226,19 @@ func (s *Service) failTask(ctx context.Context, taskID string, executionToken st
if err != nil {
return store.GatewayTask{}, err
}
if failed.Status == "cancelled" {
return failed, nil
}
if eventErr := s.emit(ctx, taskID, "task.failed", "failed", "failed", 1, message, map[string]any{"code": code, "requestId": requestID, "metrics": metrics}, simulated); eventErr != nil {
return store.GatewayTask{}, eventErr
}
return failed, nil
}
func isVolcesRemoteTaskCancellation(candidate store.RuntimeModelCandidate, err error) bool {
return isVolcesCancellationCandidate(candidate) && strings.EqualFold(clients.ErrorCode(err), "volces_task_cancelled")
}
type failedAttemptRecord struct {
Task store.GatewayTask
Body map[string]any