From 62afdbb774ffa224487869a31adcb870d98b00b6 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 03:31:13 +0000 Subject: [PATCH] perf: optimize roster check in cmd-list using Set Refactored `src/cmd-list.mjs` to use a `Set` for roster lookups, reducing complexity from O(M*N) to O(M+N). Added dependency injection to `cmdList` to enable unit testing. Added `test/cmd-list.test.mjs` to verify functionality. Co-authored-by: PR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> --- src/cmd-list.mjs | 44 ++++++++++++++++++++------------ test/cmd-list.test.mjs | 57 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 16 deletions(-) create mode 100644 test/cmd-list.test.mjs diff --git a/src/cmd-list.mjs b/src/cmd-list.mjs index 65a9166..8e36812 100644 --- a/src/cmd-list.mjs +++ b/src/cmd-list.mjs @@ -1,18 +1,29 @@ import { - getRelays, - getNamespace, + getRelays as _getRelays, + getNamespace as _getNamespace, } from './torch-config.mjs'; -import { getRoster } from './roster.mjs'; -import { queryLocks } from './lock-ops.mjs'; -import { todayDateStr, nowUnix } from './utils.mjs'; +import { getRoster as _getRoster } from './roster.mjs'; +import { queryLocks as _queryLocks } from './lock-ops.mjs'; +import { todayDateStr as _todayDateStr, nowUnix as _nowUnix } from './utils.mjs'; + +export async function cmdList(cadence, deps = {}) { + const { + getRelays = _getRelays, + getNamespace = _getNamespace, + getRoster = _getRoster, + queryLocks = _queryLocks, + todayDateStr = _todayDateStr, + nowUnix = _nowUnix, + log = console.log, + error = console.error, + } = deps; -export async function cmdList(cadence) { const relays = await getRelays(); const namespace = await getNamespace(); const dateStr = todayDateStr(); const cadences = cadence ? [cadence] : ['daily', 'weekly']; - console.error(`Listing active locks: namespace=${namespace}, cadences=${cadences.join(', ')}`); + error(`Listing active locks: namespace=${namespace}, cadences=${cadences.join(', ')}`); const results = await Promise.all( cadences.map(async (c) => { @@ -22,12 +33,12 @@ export async function cmdList(cadence) { ); for (const { c, locks } of results) { - console.log(`\n${'='.repeat(72)}`); - console.log(`Active ${namespace} ${c} locks (${dateStr})`); - console.log('='.repeat(72)); + log(`\n${'='.repeat(72)}`); + log(`Active ${namespace} ${c} locks (${dateStr})`); + log('='.repeat(72)); if (locks.length === 0) { - console.log(' (no active locks)'); + log(' (no active locks)'); continue; } @@ -38,7 +49,7 @@ export async function cmdList(cadence) { const remaining = lock.expiresAt ? lock.expiresAt - nowUnix() : null; const remainMin = remaining ? Math.round(remaining / 60) : '?'; - console.log( + log( ` ${(lock.agent ?? 'unknown').padEnd(30)} ` + `age: ${String(ageMin).padStart(4)}m ` + `ttl: ${String(remainMin).padStart(4)}m ` + @@ -48,15 +59,16 @@ export async function cmdList(cadence) { } const roster = await getRoster(c); + const rosterSet = new Set(roster); const lockedAgents = new Set(locks.map((l) => l.agent).filter(Boolean)); - const unknownLockedAgents = [...lockedAgents].filter((agent) => !roster.includes(agent)); + const unknownLockedAgents = [...lockedAgents].filter((agent) => !rosterSet.has(agent)); const available = roster.filter((a) => !lockedAgents.has(a)); if (unknownLockedAgents.length > 0) { - console.log(` Warning: lock events found with non-roster agent names: ${unknownLockedAgents.join(', ')}`); + log(` Warning: lock events found with non-roster agent names: ${unknownLockedAgents.join(', ')}`); } - console.log(`\n Locked: ${lockedAgents.size}/${roster.length}`); - console.log(` Available: ${available.join(', ') || '(none)'}`); + log(`\n Locked: ${lockedAgents.size}/${roster.length}`); + log(` Available: ${available.join(', ') || '(none)'}`); } } diff --git a/test/cmd-list.test.mjs b/test/cmd-list.test.mjs new file mode 100644 index 0000000..226cfa7 --- /dev/null +++ b/test/cmd-list.test.mjs @@ -0,0 +1,57 @@ +import { test, describe, it } from 'node:test'; +import assert from 'node:assert'; +import { cmdList } from '../src/cmd-list.mjs'; + +describe('cmdList', () => { + it('should list active locks and identify unknown agents', async () => { + const logs = []; + + const mockLocks = [ + { + agent: 'agent-1', + createdAt: 1000, + expiresAt: 4600, + eventId: 'event-1', + platform: 'linux', + }, + { + agent: 'unknown-agent', + createdAt: 2000, + eventId: 'event-2', + platform: 'mac', + }, + ]; + + const deps = { + getRelays: async () => ['wss://relay.example.com'], + getNamespace: async () => 'test-namespace', + queryLocks: async () => mockLocks, + getRoster: async () => ['agent-1', 'agent-2'], + todayDateStr: () => '2023-10-27', + nowUnix: () => 3000, // agent-1 age: 2000s (~33m), unknown-agent age: 1000s (~17m) + log: (...args) => logs.push(args.join(' ')), + error: (...args) => logs.push(args.join(' ')), + }; + + await cmdList('daily', deps); + + const output = logs.join('\n'); + // Verify header + assert.match(output, /Active test-namespace daily locks/); + + // Verify agents listed + assert.match(output, /agent-1/); + assert.match(output, /unknown-agent/); + + // Verify unknown warning + assert.match(output, /Warning: lock events found with non-roster agent names: unknown-agent/); + + // Verify summary stats + // Locked: 2 (agent-1 and unknown-agent both count as locked agents) / Roster size 2 + assert.match(output, /Locked: 2\/2/); + + // Verify available + // agent-2 is in roster and not in lockedAgents + assert.match(output, /Available: agent-2/); + }); +});