fix(desktop): wait for an evicted backend to release its slot
Await LRU teardown in each pooled backend creation path so replacement wakes do not race an exiting child for the hard spawn slot.
This commit is contained in:
@@ -290,7 +290,7 @@ import {
|
||||
localRouteFallbackProfiles,
|
||||
undialedSshRouteSeeds
|
||||
} from './plugin-profile-routes'
|
||||
import { selectPoolEvictions } from './pool-eviction'
|
||||
import { evictPoolEntries } from './pool-eviction'
|
||||
import { clampPoolLimits, parsePoolLimits, POOL_LIMITS_DEFAULTS } from './pool-limits'
|
||||
import {
|
||||
isBackgroundSlotWaitTimeout,
|
||||
@@ -1623,7 +1623,7 @@ function setPoolLimits(raw) {
|
||||
poolLimits = clampPoolLimits(raw)
|
||||
persistPoolLimits(poolLimits)
|
||||
localBackendSpawnCoordinator.setLimit(poolLimits.maxBackends)
|
||||
evictLruPoolBackends(poolMaxBackends())
|
||||
void evictLruPoolBackends(poolMaxBackends())
|
||||
startPoolIdleReaper()
|
||||
|
||||
return { ...poolLimits }
|
||||
@@ -11430,7 +11430,10 @@ async function ensureBackend(profile, opts: { passive?: boolean; spawnPriority?:
|
||||
}
|
||||
|
||||
assertNotPassiveSpawn(passive, key)
|
||||
evictLruPoolBackends(poolMaxBackends() - 1)
|
||||
// The hard slot is released only after the evicted child exits. Wait for
|
||||
// that teardown before entering the spawn queue; otherwise a successful
|
||||
// LRU choice still leaves this wake racing the old child for 30 seconds.
|
||||
await evictLruPoolBackends(poolMaxBackends() - 1)
|
||||
|
||||
const entry = {
|
||||
process: null,
|
||||
@@ -11609,7 +11612,7 @@ async function ensureRegistryBackend(
|
||||
}
|
||||
|
||||
assertNotPassiveSpawn(passive, localRoute.poolKey)
|
||||
evictLruPoolBackends(poolMaxBackends() - 1)
|
||||
await evictLruPoolBackends(poolMaxBackends() - 1)
|
||||
|
||||
const localEntry = {
|
||||
process: null,
|
||||
@@ -11683,7 +11686,7 @@ async function ensureRegistryBackend(
|
||||
}
|
||||
|
||||
assertNotPassiveSpawn(passive, key)
|
||||
evictLruPoolBackends(poolMaxBackends() - 1)
|
||||
await evictLruPoolBackends(poolMaxBackends() - 1)
|
||||
|
||||
const entry = {
|
||||
process: null,
|
||||
@@ -12334,13 +12337,17 @@ function touchPoolBackend(profile) {
|
||||
// across N registered remote connections LRU-evict a REAL local backend that
|
||||
// was merely idle past the keepalive window. Descriptors are still reclaimed
|
||||
// by the idle reaper.
|
||||
function evictLruPoolBackends(keep) {
|
||||
const evictions = selectPoolEvictions(backendPool.entries(), Math.max(0, keep), Date.now(), POOL_KEEPALIVE_FRESH_MS)
|
||||
|
||||
for (const profile of evictions) {
|
||||
rememberLog(`Evicting idle profile backend "${profile}" (LRU cap ${poolMaxBackends()})`)
|
||||
stopPoolBackend(profile)
|
||||
}
|
||||
async function evictLruPoolBackends(keep) {
|
||||
return evictPoolEntries(
|
||||
backendPool.entries(),
|
||||
Math.max(0, keep),
|
||||
Date.now(),
|
||||
POOL_KEEPALIVE_FRESH_MS,
|
||||
async profile => {
|
||||
rememberLog(`Evicting idle profile backend "${profile}" (LRU cap ${poolMaxBackends()})`)
|
||||
await stopPoolBackend(profile)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function startPoolIdleReaper() {
|
||||
|
||||
Reference in New Issue
Block a user