perf: skip unverifiable runtime process scans
This commit is contained in:
parent
9be096f864
commit
f0514a7d17
2 changed files with 88 additions and 24 deletions
|
|
@ -3719,6 +3719,7 @@ export class TeamProvisioningService {
|
|||
this.liveTeamAgentRuntimeMetadataCache.delete(teamName);
|
||||
this.liveTeamAgentRuntimeMetadataInFlightByTeam.delete(teamName);
|
||||
this.runtimeProcessRowsForUsageSnapshotByTeam.delete(teamName);
|
||||
this.runtimeProcessUsageStatsCacheByPid.clear();
|
||||
}
|
||||
|
||||
private cloneMemberSpawnStatusesSnapshot(
|
||||
|
|
@ -25329,23 +25330,30 @@ export class TeamProvisioningService {
|
|||
|
||||
let processRows: RuntimeTelemetryProcessTableRow[] = [];
|
||||
let processTableAvailable = true;
|
||||
try {
|
||||
processRows =
|
||||
this.normalizeRuntimeProcessRowsForTelemetry(
|
||||
await this.withRuntimeTelemetryTimeout(
|
||||
listRuntimeProcessTableForCurrentPlatform(),
|
||||
TeamProvisioningService.RUNTIME_PROCESS_TABLE_TIMEOUT_MS,
|
||||
'process table runtime snapshot'
|
||||
),
|
||||
process.platform === 'win32' ? 'wsl' : 'native'
|
||||
) ?? [];
|
||||
} catch (error) {
|
||||
processTableAvailable = false;
|
||||
logger.debug(
|
||||
`[${teamName}] Failed to read process table for runtime snapshot: ${
|
||||
error instanceof Error ? error.message : String(error)
|
||||
}`
|
||||
);
|
||||
const shouldReadProcessTable = this.shouldReadProcessTableForLiveRuntimeMetadata({
|
||||
metadataByMember,
|
||||
launchSnapshot: persistedLaunchSnapshot,
|
||||
paneInfoById,
|
||||
});
|
||||
if (shouldReadProcessTable) {
|
||||
try {
|
||||
processRows =
|
||||
this.normalizeRuntimeProcessRowsForTelemetry(
|
||||
await this.withRuntimeTelemetryTimeout(
|
||||
listRuntimeProcessTableForCurrentPlatform(),
|
||||
TeamProvisioningService.RUNTIME_PROCESS_TABLE_TIMEOUT_MS,
|
||||
'process table runtime snapshot'
|
||||
),
|
||||
process.platform === 'win32' ? 'wsl' : 'native'
|
||||
) ?? [];
|
||||
} catch (error) {
|
||||
processTableAvailable = false;
|
||||
logger.debug(
|
||||
`[${teamName}] Failed to read process table for runtime snapshot: ${
|
||||
error instanceof Error ? error.message : String(error)
|
||||
}`
|
||||
);
|
||||
}
|
||||
}
|
||||
this.runtimeProcessRowsForUsageSnapshotByTeam.set(teamName, {
|
||||
expiresAtMs: Date.now() + this.getAgentRuntimeSnapshotCacheTtlMs(teamName, runId),
|
||||
|
|
@ -25746,6 +25754,34 @@ export class TeamProvisioningService {
|
|||
return normalizedRows;
|
||||
}
|
||||
|
||||
private shouldReadProcessTableForLiveRuntimeMetadata(params: {
|
||||
metadataByMember: ReadonlyMap<string, LiveTeamAgentRuntimeMetadata>;
|
||||
launchSnapshot: PersistedTeamLaunchSnapshot | null | undefined;
|
||||
paneInfoById: ReadonlyMap<string, TmuxPaneRuntimeInfo>;
|
||||
}): boolean {
|
||||
for (const [memberName, metadata] of params.metadataByMember.entries()) {
|
||||
if (metadata.agentId?.trim()) {
|
||||
return true;
|
||||
}
|
||||
const paneId = metadata.tmuxPaneId?.trim() ?? '';
|
||||
if (paneId && params.paneInfoById.has(paneId)) {
|
||||
return true;
|
||||
}
|
||||
const launchRuntimePid = params.launchSnapshot?.members[memberName]?.runtimePid;
|
||||
if (
|
||||
(typeof metadata.metricsPid === 'number' &&
|
||||
Number.isFinite(metadata.metricsPid) &&
|
||||
metadata.metricsPid > 0) ||
|
||||
(typeof launchRuntimePid === 'number' &&
|
||||
Number.isFinite(launchRuntimePid) &&
|
||||
launchRuntimePid > 0)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private async readRuntimeProcessRowsForUsageSnapshot(
|
||||
teamName: string,
|
||||
options: { includeWindowsHostRows?: boolean } = {}
|
||||
|
|
|
|||
|
|
@ -3335,7 +3335,7 @@ describe('TeamProvisioningService', () => {
|
|||
getConfig: vi.fn(async () => ({
|
||||
members: [
|
||||
{ name: 'team-lead', agentType: 'team-lead' },
|
||||
{ name: 'alice', model: 'gpt-5.4-mini' },
|
||||
{ name: 'alice', model: 'gpt-5.4-mini', agentId: 'alice@runtime-team' },
|
||||
],
|
||||
})),
|
||||
};
|
||||
|
|
@ -3363,7 +3363,7 @@ describe('TeamProvisioningService', () => {
|
|||
getConfig: vi.fn(async () => ({
|
||||
members: [
|
||||
{ name: 'team-lead', agentType: 'team-lead' },
|
||||
{ name: 'alice', model: 'gpt-5.4-mini' },
|
||||
{ name: 'alice', model: 'gpt-5.4-mini', agentId: 'alice@runtime-team' },
|
||||
],
|
||||
})),
|
||||
};
|
||||
|
|
@ -3385,6 +3385,26 @@ describe('TeamProvisioningService', () => {
|
|||
expect(listRuntimeProcessTableForCurrentPlatform).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('skips live process table reads when runtime metadata has no verifiable handle', async () => {
|
||||
const svc = new TeamProvisioningService();
|
||||
(svc as any).configReader = {
|
||||
getConfig: vi.fn(async () => ({
|
||||
members: [
|
||||
{ name: 'team-lead', agentType: 'team-lead' },
|
||||
{ name: 'alice', model: 'gpt-5.4-mini' },
|
||||
],
|
||||
})),
|
||||
};
|
||||
|
||||
const metadata = (await (svc as any).getLiveTeamAgentRuntimeMetadata('runtime-team')) as Map<
|
||||
string,
|
||||
unknown
|
||||
>;
|
||||
|
||||
expect(metadata.has('alice')).toBe(true);
|
||||
expect(listRuntimeProcessTableForCurrentPlatform).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('uses a longer live runtime metadata cache for persisted teams without a tracked run', async () => {
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(new Date('2026-05-03T12:00:00.000Z'));
|
||||
|
|
@ -3393,7 +3413,7 @@ describe('TeamProvisioningService', () => {
|
|||
getConfig: vi.fn(async () => ({
|
||||
members: [
|
||||
{ name: 'team-lead', agentType: 'team-lead' },
|
||||
{ name: 'alice', model: 'gpt-5.4-mini' },
|
||||
{ name: 'alice', model: 'gpt-5.4-mini', agentId: 'alice@runtime-team' },
|
||||
],
|
||||
})),
|
||||
};
|
||||
|
|
@ -3421,7 +3441,7 @@ describe('TeamProvisioningService', () => {
|
|||
getConfig: vi.fn(async () => ({
|
||||
members: [
|
||||
{ name: 'team-lead', agentType: 'team-lead' },
|
||||
{ name: 'alice', model: 'gpt-5.4-mini' },
|
||||
{ name: 'alice', model: 'gpt-5.4-mini', agentId: 'alice@runtime-team' },
|
||||
],
|
||||
})),
|
||||
};
|
||||
|
|
@ -3441,7 +3461,7 @@ describe('TeamProvisioningService', () => {
|
|||
getConfig: vi.fn(async () => ({
|
||||
members: [
|
||||
{ name: 'team-lead', agentType: 'team-lead' },
|
||||
{ name: 'alice', model: 'gpt-5.4-mini' },
|
||||
{ name: 'alice', model: 'gpt-5.4-mini', agentId: 'alice@runtime-team' },
|
||||
],
|
||||
})),
|
||||
};
|
||||
|
|
@ -3462,7 +3482,12 @@ describe('TeamProvisioningService', () => {
|
|||
getConfig: vi.fn(async () => ({
|
||||
members: [
|
||||
{ name: 'team-lead', agentType: 'team-lead' },
|
||||
{ name: 'alice', providerId: 'opencode', model: 'gpt-5.4-mini' },
|
||||
{
|
||||
name: 'alice',
|
||||
providerId: 'opencode',
|
||||
model: 'gpt-5.4-mini',
|
||||
agentId: 'alice@runtime-team',
|
||||
},
|
||||
],
|
||||
})),
|
||||
};
|
||||
|
|
@ -4532,7 +4557,10 @@ describe('TeamProvisioningService', () => {
|
|||
(TeamProvisioningService as any).RUNTIME_PROCESS_TABLE_TIMEOUT_MS = 5;
|
||||
(svc as any).configReader = {
|
||||
getConfig: vi.fn(async () => ({
|
||||
members: [{ name: 'team-lead', agentType: 'team-lead' }],
|
||||
members: [
|
||||
{ name: 'team-lead', agentType: 'team-lead' },
|
||||
{ name: 'alice', model: 'gpt-5.4-mini', agentId: 'alice@runtime-team' },
|
||||
],
|
||||
})),
|
||||
};
|
||||
(svc as any).aliveRunByTeam.set('runtime-team', 'run-1');
|
||||
|
|
|
|||
Loading…
Reference in a new issue