From ce390d9b67854fec29d538a2cc99805550c7c6dd Mon Sep 17 00:00:00 2001 From: chiyi Date: Tue, 7 Jul 2026 12:28:02 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=8C=87=E7=BA=B9=E9=9A=8F?= =?UTF-8?q?=E6=9C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/internal/service/v1.go | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/backend/internal/service/v1.go b/backend/internal/service/v1.go index 3b24645..67508c5 100644 --- a/backend/internal/service/v1.go +++ b/backend/internal/service/v1.go @@ -1385,8 +1385,8 @@ const maxTempDeadAccounts = 3 // - tempFailover=false (default): retry the SAME account up to // maxSameAccountAttempts times (not counted); if still failing, STOP // (no fan-out — an upstream-wide blip fails identically everywhere). -// - tempFailover=true (adobe): fail over to the next account WITHOUT -// penalizing this one (rate-limit/overload isn't the account's fault), +// - tempFailover=true (adobe): disable+mark the account dead and fail over +// to the next account (ops policy: shed accounts that hit upstream errors), // capped at maxTempDeadAccounts accounts so a pool-wide blip can't fan // a single request out across everything. // - 参数错 / request-level (anything else) → return immediately, no retry, no @@ -1494,16 +1494,12 @@ func (s *V1Service) tryAccount(ctx context.Context, eventID, pool string, token } if isTemp { if tempFailover { - // Ops policy (adobe): a temporary upstream error ("system under - // load" / rate-limit) is NOT the account's fault — record the - // failure but keep the account active, and fail over to the next - // account. The pool driver caps how many accounts one request may - // burn this way (maxTempDeadAccounts). - _, _ = s.tokens.Update(ctx, pool, token.ID, map[string]any{ - "last_used_at": time.Now(), - "fail_total": gorm.Expr("fail_total + 1"), - "fails": gorm.Expr("fails + 1"), - }) + // Ops policy (adobe): treat a temporary upstream error the same as + // a fatal one — disable+mark the account dead and fail over to the + // next. The pool driver caps how many accounts one request may burn + // this way (maxTempDeadAccounts) so a pool-wide blip can't fan a + // single request across the whole pool in one shot. + s.markTokenDead(ctx, pool, token, kind) return nil, err, true, true } tempAttempts++