mirror of
https://github.com/infinition/Bjorn.git
synced 2026-03-13 16:12:00 +00:00
Add RLUtils class for managing RL/AI dashboard endpoints
- Implemented methods for fetching AI stats, training history, and recent experiences. - Added functionality to set operation mode (MANUAL, AUTO, AI) with appropriate handling. - Included helper methods for querying the database and sending JSON responses. - Integrated model metadata extraction for visualization purposes.
This commit is contained in:
103
web/js/core/resource-tracker.js
Normal file
103
web/js/core/resource-tracker.js
Normal file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* ResourceTracker — tracks intervals, timeouts, listeners, AbortControllers.
|
||||
* Each page module gets one tracker; calling cleanupAll() on unmount
|
||||
* guarantees zero leaked resources.
|
||||
*/
|
||||
export class ResourceTracker {
|
||||
constructor(label = 'anon') {
|
||||
this._label = label;
|
||||
this._intervals = new Set();
|
||||
this._timeouts = new Set();
|
||||
this._listeners = []; // {target, event, handler, options}
|
||||
this._abortControllers = new Set();
|
||||
}
|
||||
|
||||
/* -- Intervals -- */
|
||||
trackInterval(fn, ms) {
|
||||
const id = setInterval(fn, ms);
|
||||
this._intervals.add(id);
|
||||
return id;
|
||||
}
|
||||
|
||||
clearTrackedInterval(id) {
|
||||
clearInterval(id);
|
||||
this._intervals.delete(id);
|
||||
}
|
||||
|
||||
/* -- Timeouts -- */
|
||||
trackTimeout(fn, ms) {
|
||||
const id = setTimeout(() => {
|
||||
this._timeouts.delete(id);
|
||||
fn();
|
||||
}, ms);
|
||||
this._timeouts.add(id);
|
||||
return id;
|
||||
}
|
||||
|
||||
clearTrackedTimeout(id) {
|
||||
clearTimeout(id);
|
||||
this._timeouts.delete(id);
|
||||
}
|
||||
|
||||
/* -- Event listeners -- */
|
||||
trackEventListener(target, event, handler, options) {
|
||||
target.addEventListener(event, handler, options);
|
||||
this._listeners.push({ target, event, handler, options });
|
||||
}
|
||||
|
||||
/* -- AbortControllers (for fetch) -- */
|
||||
trackAbortController() {
|
||||
const ac = new AbortController();
|
||||
this._abortControllers.add(ac);
|
||||
return ac;
|
||||
}
|
||||
|
||||
removeAbortController(ac) {
|
||||
this._abortControllers.delete(ac);
|
||||
}
|
||||
|
||||
/* -- Cleanup everything -- */
|
||||
cleanupAll() {
|
||||
// Intervals
|
||||
for (const id of this._intervals) clearInterval(id);
|
||||
this._intervals.clear();
|
||||
|
||||
// Timeouts
|
||||
for (const id of this._timeouts) clearTimeout(id);
|
||||
this._timeouts.clear();
|
||||
|
||||
// Listeners & Generic cleanups
|
||||
for (const item of this._listeners) {
|
||||
if (item.cleanup) {
|
||||
try { item.cleanup(); } catch (err) { console.warn(`[ResourceTracker:${this._label}] cleanup error`, err); }
|
||||
} else if (item.target) {
|
||||
item.target.removeEventListener(item.event, item.handler, item.options);
|
||||
}
|
||||
}
|
||||
this._listeners.length = 0;
|
||||
|
||||
// Abort controllers
|
||||
for (const ac of this._abortControllers) {
|
||||
try { ac.abort(); } catch { /* already aborted */ }
|
||||
}
|
||||
this._abortControllers.clear();
|
||||
}
|
||||
|
||||
/* -- Generic resources -- */
|
||||
trackResource(fn) {
|
||||
if (typeof fn === 'function') {
|
||||
this._listeners.push({ cleanup: fn });
|
||||
}
|
||||
}
|
||||
|
||||
/* -- Diagnostics -- */
|
||||
stats() {
|
||||
return {
|
||||
label: this._label,
|
||||
intervals: this._intervals.size,
|
||||
timeouts: this._timeouts.size,
|
||||
listeners: this._listeners.length,
|
||||
abortControllers: this._abortControllers.size
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user