Reuse fixed SQL statements for observation pruning
This commit is contained in:
@@ -428,11 +428,11 @@ export function pruneHostObservations(): number {
|
|||||||
const rows = handle.prepare(`SELECT id FROM ec_host_operations WHERE observation_success=1 AND state='completed'
|
const rows = handle.prepare(`SELECT id FROM ec_host_operations WHERE observation_success=1 AND state='completed'
|
||||||
AND updated_at<? ORDER BY updated_at LIMIT 500`).all(cutoff) as { id: string }[];
|
AND updated_at<? ORDER BY updated_at LIMIT 500`).all(cutoff) as { id: string }[];
|
||||||
if (!rows.length) return 0;
|
if (!rows.length) return 0;
|
||||||
const ids = rows.map(row => row.id);
|
// Fixed SQL text prevents each batch size from adding three cached statements.
|
||||||
const placeholders = ids.map(() => '?').join(',');
|
const ids = JSON.stringify(rows.map(row => row.id));
|
||||||
handle.prepare(`DELETE FROM ec_host_operation_events WHERE operation_id IN (${placeholders})`).run(...ids);
|
handle.prepare('DELETE FROM ec_host_operation_events WHERE operation_id IN (SELECT value FROM json_each(?))').run(ids);
|
||||||
handle.prepare(`DELETE FROM ec_host_operation_payloads WHERE operation_id IN (${placeholders})`).run(...ids);
|
handle.prepare('DELETE FROM ec_host_operation_payloads WHERE operation_id IN (SELECT value FROM json_each(?))').run(ids);
|
||||||
return handle.prepare(`DELETE FROM ec_host_operations WHERE id IN (${placeholders})`).run(...ids).changes;
|
return handle.prepare('DELETE FROM ec_host_operations WHERE id IN (SELECT value FROM json_each(?))').run(ids).changes;
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
/** Heartbeats can tell an executing create to stop at its next safe command boundary. */
|
/** Heartbeats can tell an executing create to stop at its next safe command boundary. */
|
||||||
|
|||||||
@@ -141,6 +141,31 @@ describe('routine host observation retention', () => {
|
|||||||
expect(api.handle.prepare("SELECT COUNT(*) AS count FROM ec_host_operations WHERE kind='instance.restart'").get()).toEqual({ count: 2000 });
|
expect(api.handle.prepare("SELECT COUNT(*) AS count FROM ec_host_operations WHERE kind='instance.restart'").get()).toEqual({ count: 2000 });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('reuses the same three delete statements across different batch sizes', async () => {
|
||||||
|
const api = await setup();
|
||||||
|
const statements = new Map<string, ReturnType<typeof api.handle.prepare>>();
|
||||||
|
for (const count of [1, 2, 7, 50, 500]) {
|
||||||
|
api.handle.transaction(() => {
|
||||||
|
const insert = api.handle.prepare(`INSERT INTO ec_host_operations
|
||||||
|
(id,host_id,kind,payload,state,created_at,updated_at,observation_success)
|
||||||
|
VALUES(?,?,'files.stat','{}','completed',?,?,1)`);
|
||||||
|
for (let i = 0; i < count; i++) insert.run(`read-${count}-${i}`, api.host.id, at(2 * day), at(2 * day));
|
||||||
|
})();
|
||||||
|
const prepare = vi.spyOn(api.handle, 'prepare');
|
||||||
|
expect(api.pruneHostObservations()).toBe(count);
|
||||||
|
const deletes = prepare.mock.calls.map(([sql]) => sql).filter(sql => sql.startsWith('DELETE FROM ec_host_'));
|
||||||
|
prepare.mockRestore();
|
||||||
|
expect(deletes).toHaveLength(3);
|
||||||
|
for (const sql of deletes) {
|
||||||
|
const statement = api.handle.prepare(sql);
|
||||||
|
if (statements.has(sql)) expect(statement).toBe(statements.get(sql));
|
||||||
|
statements.set(sql, statement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect(statements.size).toBe(3);
|
||||||
|
expect(api.handle.pragma('foreign_key_check')).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
it('backfills legacy observation classification once while preserving actions and negative or invalid results', async () => {
|
it('backfills legacy observation classification once while preserving actions and negative or invalid results', async () => {
|
||||||
const api = await setup();
|
const api = await setup();
|
||||||
const read = api.add('files.manifest');
|
const read = api.add('files.manifest');
|
||||||
|
|||||||
Reference in New Issue
Block a user