perf: hourly update check only with a browser open; opt-in retention, incremental auto-vacuum and Compact
- update-scheduler: default interval 1 h (DASHBOARD_UPDATE_CHECK_INTERVAL_MS and its 60 s floor kept); a scheduled tick with no /ws client is skipped, and the next browser to connect gets one catch-up check when the last one is stale (websocket.js onConnection). Manual check unchanged. - db-retention.js: shared session purge (used by POST /api/settings/cleanup too), opt-in AGENTHUB_RETENTION_DAYS applied by the hourly maintenance in 25-session transactions with yields (max 5000/run), bounded incremental_vacuum when the freelist is large, and a manual Compact (VACUUM in a worker, converting to auto_vacuum=INCREMENTAL). - db.js: new databases are INCREMENTAL; an existing one up to 32 MB is converted at startup. - GET/PUT /api/settings/retention, POST /api/settings/compact (confirm: true); Settings → Data → Session cleanup gets the Automatic cleanup control and Compact now (en + vi).
This commit is contained in:
@@ -1649,6 +1649,23 @@ export const api = {
|
||||
/** POST /api/settings/backup/run — starts one; poll `get` while `running` */
|
||||
run: () => request<BackupState & { ok: boolean }>("/settings/backup/run", { method: "POST" }),
|
||||
},
|
||||
/** Opt-in automatic retention and Compact (`server/lib/db-retention.js`). */
|
||||
retention: {
|
||||
/** GET /api/settings/retention */
|
||||
get: () => request<RetentionState>("/settings/retention"),
|
||||
/** PUT /api/settings/retention — `days` 0 turns it off */
|
||||
save: (days: number) =>
|
||||
request<RetentionState & { ok: boolean }>("/settings/retention", {
|
||||
method: "PUT",
|
||||
body: JSON.stringify({ days }),
|
||||
}),
|
||||
/** POST /api/settings/compact — a full VACUUM; poll `get` while `compacting` */
|
||||
compact: () =>
|
||||
request<RetentionState & { ok: boolean }>("/settings/compact", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ confirm: true }),
|
||||
}),
|
||||
},
|
||||
/** The bearer token for `POST /api/hooks/ingest-batch`. Only its hash is
|
||||
* stored: `rotate` returns the new token this once, `get` never does. */
|
||||
pushToken: {
|
||||
@@ -5461,6 +5478,36 @@ export interface BackupState {
|
||||
env_owned: { dir: boolean; hour: boolean; keep: boolean };
|
||||
}
|
||||
|
||||
/** GET /api/settings/retention. `days` 0 = automatic retention off;
|
||||
* `last_run`/`last_compact` are this server process's own. */
|
||||
export interface RetentionState {
|
||||
days: number;
|
||||
max_days: number;
|
||||
env_owned: { days: boolean };
|
||||
last_run: {
|
||||
at: string;
|
||||
retention?: { purged_sessions: number; purged_events: number; error?: string };
|
||||
reclaim?: { reclaimed_pages: number; error?: string };
|
||||
} | null;
|
||||
space: {
|
||||
auto_vacuum: "none" | "full" | "incremental";
|
||||
page_size: number;
|
||||
page_count: number;
|
||||
freelist_pages: number;
|
||||
free_bytes: number;
|
||||
} | null;
|
||||
db_size: number;
|
||||
compacting: boolean;
|
||||
last_compact: {
|
||||
at: string;
|
||||
ok: boolean;
|
||||
size_before?: number;
|
||||
size_after?: number;
|
||||
ms?: number;
|
||||
error?: string;
|
||||
} | null;
|
||||
}
|
||||
|
||||
/** GET /api/settings/push-token — whether push ingest is on; never the token. */
|
||||
export interface PushTokenStatus {
|
||||
enabled: boolean;
|
||||
|
||||
Reference in New Issue
Block a user