fix(team): repair runtime snapshot caching and rss sampling regressions
Pre-existing regressions из 'cache transcript and telemetry scans': - pidsMissingUsageStats теперь всегда фильтрует runtimeUsagePids по отсутствию stats, а не только когда runtimeProcessRowsForSnapshot null. Пустой/неполный results-row больше не блокирует pidusage fallback. - Кэш runtimeProcessTableCache очищается при invalidateRuntime- SnapshotCaches и не репопулируется in-flight'ом, который начат до invalidate (через generation token + caller-aware cache context). - runtimeProcessUsageStatsCacheByPid очищается в invalidate, а в shared OpenCode host refresh branch'е сбрасывается negative-cache для конкретного pid'а перед таргетным sample'ом. Зеленит 25 теста в TeamProvisioningService > getTeamAgentRuntimeSnapshot, включая 'uses batched pidusage rss values', 'captures CPU and memory history', 'does not cache live runtime metadata when invalidated while the probe is in flight', 'shows RSS for OpenCode secondary lane host pids'.
This commit is contained in:
parent
9e3efa18ce
commit
cb35992cff
1 changed files with 24 additions and 11 deletions
|
|
@ -3463,6 +3463,7 @@ export class TeamProvisioningService {
|
||||||
private runtimeProcessTableInFlight:
|
private runtimeProcessTableInFlight:
|
||||||
| Promise<RuntimeTelemetryProcessTableRow[] | null>
|
| Promise<RuntimeTelemetryProcessTableRow[] | null>
|
||||||
| undefined;
|
| undefined;
|
||||||
|
private runtimeProcessTableCacheGeneration = 0;
|
||||||
private readonly runtimeProcessUsageStatsCacheByPid = new Map<
|
private readonly runtimeProcessUsageStatsCacheByPid = new Map<
|
||||||
number,
|
number,
|
||||||
{
|
{
|
||||||
|
|
@ -3781,6 +3782,9 @@ export class TeamProvisioningService {
|
||||||
this.liveTeamAgentRuntimeMetadataCache.delete(teamName);
|
this.liveTeamAgentRuntimeMetadataCache.delete(teamName);
|
||||||
this.liveTeamAgentRuntimeMetadataInFlightByTeam.delete(teamName);
|
this.liveTeamAgentRuntimeMetadataInFlightByTeam.delete(teamName);
|
||||||
this.runtimeProcessRowsForUsageSnapshotByTeam.delete(teamName);
|
this.runtimeProcessRowsForUsageSnapshotByTeam.delete(teamName);
|
||||||
|
this.runtimeProcessUsageStatsCacheByPid.clear();
|
||||||
|
this.runtimeProcessTableCache = undefined;
|
||||||
|
this.runtimeProcessTableCacheGeneration += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private normalizeMemberKeyForTaskActivity(memberName: string): string {
|
private normalizeMemberKeyForTaskActivity(memberName: string): string {
|
||||||
|
|
@ -14307,10 +14311,7 @@ export class TeamProvisioningService {
|
||||||
runtimeProcessRowsForSnapshot,
|
runtimeProcessRowsForSnapshot,
|
||||||
runtimeUsagePids
|
runtimeUsagePids
|
||||||
);
|
);
|
||||||
const pidsMissingUsageStats =
|
const pidsMissingUsageStats = runtimeUsagePids.filter((pid) => !usageStatsByPid.has(pid));
|
||||||
runtimeProcessRowsForSnapshot == null
|
|
||||||
? runtimeUsagePids.filter((pid) => !usageStatsByPid.has(pid))
|
|
||||||
: [];
|
|
||||||
if (pidsMissingUsageStats.length > 0) {
|
if (pidsMissingUsageStats.length > 0) {
|
||||||
const sampledUsageStats = await this.readProcessUsageStatsByPid(pidsMissingUsageStats);
|
const sampledUsageStats = await this.readProcessUsageStatsByPid(pidsMissingUsageStats);
|
||||||
for (const [pid, stats] of sampledUsageStats) {
|
for (const [pid, stats] of sampledUsageStats) {
|
||||||
|
|
@ -14641,11 +14642,11 @@ export class TeamProvisioningService {
|
||||||
rssPid &&
|
rssPid &&
|
||||||
!usageStatsByPid.has(rssPid) &&
|
!usageStatsByPid.has(rssPid) &&
|
||||||
isSharedOpenCodeHost &&
|
isSharedOpenCodeHost &&
|
||||||
runtimeProcessRowsForSnapshot == null &&
|
|
||||||
typeof rssPid === 'number' &&
|
typeof rssPid === 'number' &&
|
||||||
rssPid > 0
|
rssPid > 0
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
this.runtimeProcessUsageStatsCacheByPid.delete(rssPid);
|
||||||
const refreshedUsageStats = (await this.readProcessUsageStatsByPid([rssPid])).get(rssPid);
|
const refreshedUsageStats = (await this.readProcessUsageStatsByPid([rssPid])).get(rssPid);
|
||||||
if (refreshedUsageStats) {
|
if (refreshedUsageStats) {
|
||||||
usageStatsByPid.set(rssPid, refreshedUsageStats);
|
usageStatsByPid.set(rssPid, refreshedUsageStats);
|
||||||
|
|
@ -25795,7 +25796,8 @@ export class TeamProvisioningService {
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentProcessRows = await this.readCurrentRuntimeProcessTableRows(
|
const currentProcessRows = await this.readCurrentRuntimeProcessTableRows(
|
||||||
'process table runtime snapshot'
|
'process table runtime snapshot',
|
||||||
|
{ teamName, generationAtStart }
|
||||||
);
|
);
|
||||||
const processRows = currentProcessRows ?? [];
|
const processRows = currentProcessRows ?? [];
|
||||||
const processTableAvailable = currentProcessRows !== null;
|
const processTableAvailable = currentProcessRows !== null;
|
||||||
|
|
@ -26610,7 +26612,8 @@ export class TeamProvisioningService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async readCurrentRuntimeProcessTableRows(
|
private async readCurrentRuntimeProcessTableRows(
|
||||||
label: string
|
label: string,
|
||||||
|
cacheContext?: { teamName: string; generationAtStart: number }
|
||||||
): Promise<RuntimeTelemetryProcessTableRow[] | null> {
|
): Promise<RuntimeTelemetryProcessTableRow[] | null> {
|
||||||
const cached = this.runtimeProcessTableCache;
|
const cached = this.runtimeProcessTableCache;
|
||||||
if (cached && cached.expiresAtMs > Date.now()) {
|
if (cached && cached.expiresAtMs > Date.now()) {
|
||||||
|
|
@ -26621,6 +26624,7 @@ export class TeamProvisioningService {
|
||||||
return this.runtimeProcessTableInFlight;
|
return this.runtimeProcessTableInFlight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const generationAtStart = this.runtimeProcessTableCacheGeneration;
|
||||||
const request = this.withRuntimeTelemetryTimeout(
|
const request = this.withRuntimeTelemetryTimeout(
|
||||||
listRuntimeProcessTableForCurrentPlatform(),
|
listRuntimeProcessTableForCurrentPlatform(),
|
||||||
TeamProvisioningService.RUNTIME_PROCESS_TABLE_TIMEOUT_MS,
|
TeamProvisioningService.RUNTIME_PROCESS_TABLE_TIMEOUT_MS,
|
||||||
|
|
@ -26642,10 +26646,19 @@ export class TeamProvisioningService {
|
||||||
return null;
|
return null;
|
||||||
})
|
})
|
||||||
.then((rows) => {
|
.then((rows) => {
|
||||||
this.runtimeProcessTableCache = {
|
const callerGenerationStillValid =
|
||||||
expiresAtMs: Date.now() + TeamProvisioningService.RUNTIME_PROCESS_TABLE_CACHE_TTL_MS,
|
cacheContext === undefined ||
|
||||||
rows,
|
this.getRuntimeSnapshotCacheGeneration(cacheContext.teamName) ===
|
||||||
};
|
cacheContext.generationAtStart;
|
||||||
|
if (
|
||||||
|
this.runtimeProcessTableCacheGeneration === generationAtStart &&
|
||||||
|
callerGenerationStillValid
|
||||||
|
) {
|
||||||
|
this.runtimeProcessTableCache = {
|
||||||
|
expiresAtMs: Date.now() + TeamProvisioningService.RUNTIME_PROCESS_TABLE_CACHE_TTL_MS,
|
||||||
|
rows,
|
||||||
|
};
|
||||||
|
}
|
||||||
return rows;
|
return rows;
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue