mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-08-17 18:25:42 +02:00
60 lines
2.4 KiB
JavaScript
60 lines
2.4 KiB
JavaScript
// Memory pressure stops being a telemetry event and starts being ACTED on (ENG-320).
|
|
//
|
|
// The sensor next door has watched sessions climb to 3-4GB for weeks and only ever reported it:
|
|
// 18 of 57 active users tripped it in one day, and the observed end state is macOS killing the
|
|
// app with NO trace at all (one such death was caught live mid-capturePage under heavy webviews).
|
|
// A silent kill costs the whole session; everything this module gives up under pressure is
|
|
// re-fetchable or cosmetic, which is the whole trade.
|
|
//
|
|
// Levers, in order of engagement when the cap is crossed:
|
|
// 1. thumbnails stop: capture-page composites GPU surfaces (big transient allocations, and the
|
|
// last logged act before the observed silent death); callers already treat
|
|
// null as "keep the last preview", so this degrades invisibly
|
|
// 2. HTTP caches drop: refetchable bytes, same clear the ENG-247 boot sweep does
|
|
//
|
|
// Hysteresis mirrors the sensor: enter at the cap, exit below 80% of it, one action set per
|
|
// episode so a session hovering at the line cannot thrash the caches.
|
|
'use strict';
|
|
|
|
let p_underPressure = false;
|
|
let p_episodes = 0;
|
|
let p_actions = null;
|
|
|
|
/** Wire the action set once at boot; separated for tests and so this file stays require-clean. */
|
|
function initMemoryRelief(actions) {
|
|
p_actions = actions || null;
|
|
}
|
|
|
|
/** Called by the sensor with every sample. Returns true when the pressure state CHANGED. */
|
|
function updateMemoryPressure(totalMb, capMb) {
|
|
if (!p_underPressure && totalMb >= capMb) {
|
|
p_underPressure = true;
|
|
p_episodes += 1;
|
|
try { console.error('[memory-relief] entering pressure mode at', totalMb, 'MB (episode', p_episodes + ')'); } catch (_) {}
|
|
if (p_actions) {
|
|
try { p_actions.clearCaches && p_actions.clearCaches(); } catch (_) {}
|
|
}
|
|
return true;
|
|
}
|
|
if (p_underPressure && totalMb < capMb * 0.8) {
|
|
p_underPressure = false;
|
|
try { console.error('[memory-relief] pressure cleared at', totalMb, 'MB'); } catch (_) {}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/** The capture-page gate: while under pressure, thumbnails yield rather than composite. */
|
|
function underMemoryPressure() {
|
|
return p_underPressure;
|
|
}
|
|
|
|
/** Test hook. */
|
|
function resetMemoryRelief() {
|
|
p_underPressure = false;
|
|
p_episodes = 0;
|
|
p_actions = null;
|
|
}
|
|
|
|
module.exports = { initMemoryRelief, updateMemoryPressure, underMemoryPressure, resetMemoryRelief };
|