refactor: route TPM reservation and settlement through the derived value
Five call sites (QuotaGate entry, RetryMW/EmbeddingClient success and transient-failure settlement) now read effective_est_tokens() instead of est_tokens. Success paths gain an unavailable branch that keeps delta at zero once usage frames may be missing; it has no producer yet, so behaviour is unchanged while the tpm>0 => est_tokens>0 gate still holds.
This commit is contained in:
@@ -23,7 +23,7 @@ class QuotaGate:
|
||||
|
||||
async def try_acquire(self, source: SourceConfig) -> Permit | None:
|
||||
try:
|
||||
return await self._limiter.try_acquire(source.name, source.est_tokens)
|
||||
return await self._limiter.try_acquire(source.name, source.effective_est_tokens())
|
||||
except GovernanceBackendError:
|
||||
raise
|
||||
except Exception as exc:
|
||||
|
||||
@@ -335,7 +335,12 @@ class RetryMW:
|
||||
overlay=request.overlay,
|
||||
call_id=call_id,
|
||||
)
|
||||
actual = result.prompt_tokens + result.completion_tokens
|
||||
if result.usage_source == "unavailable":
|
||||
# 用量不可得时按入场预扣量结算(delta==0),否则押金会被整笔退回,
|
||||
# 对"从不返回 usage 帧"的源等于 TPM 闸失效(设计 §3.2 #9)
|
||||
actual = source.effective_est_tokens()
|
||||
else:
|
||||
actual = result.prompt_tokens + result.completion_tokens
|
||||
await self._record_quietly(self._breaker.record_success(entry))
|
||||
await self._record_quietly(self._quota.mark_progress())
|
||||
self._feed_outcome(source.name, ok=True)
|
||||
@@ -367,7 +372,8 @@ class RetryMW:
|
||||
self._pacer.on_backpressure(source.name)
|
||||
await self._record_quietly(self._breaker.record_failure(entry, reason, dead))
|
||||
if not dead:
|
||||
actual = source.est_tokens # 保守: 失败请求可能已被网关计费(CHS 同款)
|
||||
# 保守: 失败请求可能已被网关计费(CHS 同款);与入场预扣同源取值
|
||||
actual = source.effective_est_tokens()
|
||||
await self._emit(request, source, call_id, started, error=exc)
|
||||
return _Failed(exc, immediate=dead)
|
||||
finally:
|
||||
|
||||
Reference in New Issue
Block a user