Repository navigation
refactor(combo): god-file split D7a — round-robin sticky state to combo/rrState.ts (QG v2 Fase 9 T5) - #4196
Conversation
… (QG v2 Fase 9 T5 D7a)
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Code Review
This pull request refactors the round-robin sticky state and its associated helpers from open-sse/services/combo.ts into a new dedicated module open-sse/services/combo/rrState.ts. The review feedback recommends adding defensive checks in getStickyRoundRobinStartIndex and recordStickyRoundRobinSuccess to handle empty or undefined inputs, preventing potential runtime issues such as division by zero or type errors.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| export function getStickyRoundRobinStartIndex( | ||
| comboName: string, | ||
| targets: ResolvedComboTarget[], | ||
| stickyLimit: number | ||
| ): { startIndex: number; counter: number } { | ||
| const sticky = rrStickyTargets.get(comboName); | ||
| const stickyIndex = sticky | ||
| ? targets.findIndex((target) => target.executionKey === sticky.executionKey) | ||
| : -1; | ||
| if (stickyLimit > 1 && sticky && stickyIndex >= 0 && sticky.successCount < stickyLimit) { | ||
| return { startIndex: stickyIndex, counter: rrCounters.get(comboName) || 0 }; | ||
| } | ||
|
|
||
| const counter = rrCounters.get(comboName) || 0; | ||
| return { startIndex: counter % targets.length, counter }; | ||
| } |
There was a problem hiding this comment.
Para aplicar programação defensiva e evitar possíveis erros em tempo de execução (como um erro de tipo se targets for nulo/indefinido, ou NaN se targets estiver vazio devido à divisão por zero em counter % targets.length), é recomendável adicionar uma verificação defensiva no início da função.
export function getStickyRoundRobinStartIndex(
comboName: string,
targets: ResolvedComboTarget[],
stickyLimit: number
): { startIndex: number; counter: number } {
const counter = rrCounters.get(comboName) || 0;
if (!targets || targets.length === 0) {
return { startIndex: 0, counter };
}
const sticky = rrStickyTargets.get(comboName);
const stickyIndex = sticky
? targets.findIndex((target) => target.executionKey === sticky.executionKey)
: -1;
if (stickyLimit > 1 && sticky && stickyIndex >= 0 && sticky.successCount < stickyLimit) {
return { startIndex: stickyIndex, counter };
}
return { startIndex: counter % targets.length, counter };
}| export function recordStickyRoundRobinSuccess( | ||
| comboName: string, | ||
| target: ResolvedComboTarget, | ||
| stickyLimit: number, | ||
| targets: ResolvedComboTarget[] | ||
| ): void { | ||
| const sticky = rrStickyTargets.get(comboName); | ||
| const successCount = sticky?.executionKey === target.executionKey ? sticky.successCount + 1 : 1; | ||
| if (successCount >= stickyLimit) { | ||
| const servedIndex = targets.findIndex((entry) => entry.executionKey === target.executionKey); | ||
| rrCounters.set( | ||
| comboName, | ||
| servedIndex >= 0 ? servedIndex + 1 : (rrCounters.get(comboName) || 0) + 1 | ||
| ); | ||
| rrStickyTargets.delete(comboName); | ||
| return; | ||
| } | ||
|
|
||
| rrStickyTargets.set(comboName, { executionKey: target.executionKey, successCount }); | ||
| } |
There was a problem hiding this comment.
Para aplicar programação defensiva, devemos adicionar uma verificação para lidar com casos em que target ou targets sejam nulos/indefinidos ou vazios, evitando possíveis falhas em tempo de execução (como um erro de tipo ao acessar target.executionKey ou ao chamar targets.findIndex).
export function recordStickyRoundRobinSuccess(
comboName: string,
target: ResolvedComboTarget,
stickyLimit: number,
targets: ResolvedComboTarget[]
): void {
if (!target || !targets || targets.length === 0) return;
const sticky = rrStickyTargets.get(comboName);
const successCount = sticky?.executionKey === target.executionKey ? sticky.successCount + 1 : 1;
if (successCount >= stickyLimit) {
const servedIndex = targets.findIndex((entry) => entry.executionKey === target.executionKey);
rrCounters.set(
comboName,
servedIndex >= 0 ? servedIndex + 1 : (rrCounters.get(comboName) || 0) + 1
);
rrStickyTargets.delete(comboName);
return;
}
rrStickyTargets.set(comboName, { executionKey: target.executionKey, successCount });
}… (QG v2 Fase 9 T5 D7a) (cheaper-inference#4196) Integrated into release/v3.8.29 — D7a round-robin sticky state extracted byte-identically to combo/rrState.ts; reconciled with cheaper-inference#4194 (baseline combo.ts -> 3398, resolving the over-cap left by cheaper-inference#4194).
O que
Continuação do split do god-file
open-sse/services/combo.ts(Quality Gate v2 / Fase 9 T5), D7a — primeira metade do D7 (estado de roteamento). Extrai o bloco de estado round-robin para o novo leafopen-sse/services/combo/rrState.ts. Move byte-idêntico, zero mudança de comportamento.combo.ts3431 → 3388 LOC (−43);rrState.ts71 LOC.Movido para
combo/rrState.ts(6 símbolos)MAX_RR_COUNTERS,rrCounters(Map),rrStickyTargets(Map),clampStickyRoundRobinTargetLimit,getStickyRoundRobinStartIndex,recordStickyRoundRobinSuccess.⭐ Coesão de estado (o ponto do D7)
rrCounters/rrStickyTargetssão mutados em vários lugares — os 3 helpers movidos e código que fica no combo.ts (orderTargetsByResetAwareQuota,orderTargetsByResetWindow,handleRoundRobinCombo). Após o move, cada Map permanece instância única definida 1× em rrState.ts; o combo.ts importa as mesmas referências de volta e muta direto. Verificado:new Mapde rrCounters/rrStickyTargets = 0 no combo.ts, 2 no rrState.ts.rrState.tsé leaf puro — importa sóResolvedComboTargetde./types.ts, nada do barrel../combo(sem ciclo).Validação
typecheck:corerc=0 (0 erros TS) · lint escopado rc=0combo-routing-e2e.test.ts(sticky-3) PASS — guarda decisiva de que o estado round-robin sobreviveu como instância únicacheck:cyclesrc=0 ·check:file-sizerc=0 (baselinecombo.ts→ 3389)new Mapcount 0 no combo.ts, cada símbolo def 1×, sem barrel, diff move-only.Refactor puro — testes existentes são a guarda de regressão.
🤖 Generated with Claude Code