Fix recommend.js: include allowed_warning in provider selection
allowed_warning providers can serve requests — only the budget is approaching its limit. Previously they were excluded from both Phase 1 and Phase 2 selection, causing unnecessary escalation to shelley-proxy emergency fallback when team-vigilio was at 79% 7d (allowed_warning) and team-ludo was showing invalid_key in the health-pulse cache. Now: - Phase 1: first provider under threshold with status allowed or allowed_warning - Phase 2: lowest-utilization provider with either status; reason notes warning Effect: next wake picks team-vigilio (79% 7d, warning) instead of shelley-proxy. Shelley-proxy is now a true last resort again.
This commit is contained in:
parent
ab35cc8346
commit
e52ba2921c
1 changed files with 11 additions and 8 deletions
19
recommend.js
19
recommend.js
|
|
@ -6,10 +6,10 @@
|
|||
* Returns the best Teams provider considering 7d budget utilization.
|
||||
*
|
||||
* Selection rules:
|
||||
* 1. status must be "allowed"
|
||||
* 1. status must be "allowed" or "allowed_warning" (both can serve requests)
|
||||
* 2. Scan chain in order; take first with utilization_7d < SWITCH_THRESHOLD
|
||||
* 3. If none under threshold, take lowest-utilization allowed provider
|
||||
* 4. If no allowed Teams providers, return emergency=true (shelley-proxy)
|
||||
* 3. If none under threshold, take lowest-utilization allowed/allowed_warning provider
|
||||
* 4. If no usable Teams providers, return emergency=true (shelley-proxy)
|
||||
*
|
||||
* Usage:
|
||||
* node recommend.js # JSON output
|
||||
|
|
@ -90,10 +90,11 @@ async function main() {
|
|||
.filter(name => providers[name] && providers[name].type === 'teams-direct')
|
||||
.map(name => ({ name, ...providers[name] }));
|
||||
|
||||
// Phase 1: first provider under threshold with status=allowed
|
||||
// Phase 1: first provider under threshold with status=allowed or allowed_warning
|
||||
// Both statuses can serve requests; allowed_warning just means approaching limit
|
||||
let best = null;
|
||||
for (const p of candidates) {
|
||||
if (p.status === 'allowed') {
|
||||
if (p.status === 'allowed' || p.status === 'allowed_warning') {
|
||||
const util7d = p.utilization_7d ?? 0;
|
||||
if (util7d < SWITCH_THRESHOLD) {
|
||||
best = {
|
||||
|
|
@ -105,12 +106,13 @@ async function main() {
|
|||
}
|
||||
}
|
||||
|
||||
// Phase 2: all over threshold — pick lowest 7d utilization that's still allowed
|
||||
// Phase 2: all over threshold — pick lowest 7d utilization (allowed or allowed_warning)
|
||||
// Prefer allowed over allowed_warning; both beat emergency fallback
|
||||
if (!best) {
|
||||
let lowestUtil = Infinity;
|
||||
let lowestCandidate = null;
|
||||
for (const p of candidates) {
|
||||
if (p.status === 'allowed') {
|
||||
if (p.status === 'allowed' || p.status === 'allowed_warning') {
|
||||
const util7d = p.utilization_7d ?? 0;
|
||||
if (util7d < lowestUtil) {
|
||||
lowestUtil = util7d;
|
||||
|
|
@ -119,9 +121,10 @@ async function main() {
|
|||
}
|
||||
}
|
||||
if (lowestCandidate) {
|
||||
const warningTag = lowestCandidate.status === 'allowed_warning' ? ', warning' : '';
|
||||
best = {
|
||||
name: lowestCandidate.name,
|
||||
reason: `all over threshold — best available at ${pct(lowestUtil)} 7d (data: ${source})`,
|
||||
reason: `all over threshold — best available at ${pct(lowestUtil)} 7d${warningTag} (data: ${source})`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue