feat: rebuild warm operations workbench
This commit is contained in:
@@ -10,6 +10,8 @@ export interface InstanceResources {
|
||||
readonly memoryPercent?: number;
|
||||
readonly maxTemperatureCelsius?: number;
|
||||
readonly phoneNumbers?: readonly string[];
|
||||
readonly version?: string;
|
||||
readonly platform?: string;
|
||||
}
|
||||
|
||||
const MAX_BODY_BYTES = 32_768;
|
||||
@@ -32,6 +34,31 @@ function data(response: UpstreamResponse): Record<string, unknown> | undefined {
|
||||
}
|
||||
}
|
||||
|
||||
const safeText = (value: unknown, maximum = 128): string | undefined =>
|
||||
typeof value === 'string' &&
|
||||
value.length > 0 &&
|
||||
value.length <= maximum &&
|
||||
!/[\u0000-\u001f\u007f]/u.test(value)
|
||||
? value
|
||||
: undefined;
|
||||
|
||||
export function parseHealth(response: UpstreamResponse): InstanceResources {
|
||||
if (response.status < 200 || response.status >= 300) return {};
|
||||
if (Buffer.byteLength(response.body, 'utf8') > MAX_BODY_BYTES) return {};
|
||||
try {
|
||||
const root = record(JSON.parse(response.body));
|
||||
if (!root) return {};
|
||||
const version = safeText(root.version);
|
||||
const platform = safeText(root.platform);
|
||||
return {
|
||||
...(version ? { version } : {}),
|
||||
...(platform ? { platform } : {}),
|
||||
};
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
export function parseStats(response: UpstreamResponse): InstanceResources {
|
||||
const value = data(response);
|
||||
if (!value) return {};
|
||||
@@ -43,10 +70,20 @@ export function parseStats(response: UpstreamResponse): InstanceResources {
|
||||
.filter((item): item is number => item !== undefined)
|
||||
: [];
|
||||
const maxTemperatureCelsius = temperatures.length > 0 ? Math.max(...temperatures) : undefined;
|
||||
const system = record(value.system);
|
||||
const version =
|
||||
safeText(value.version) ??
|
||||
safeText(value.current_version) ??
|
||||
safeText(system?.version) ??
|
||||
safeText(system?.app_version);
|
||||
const platform =
|
||||
safeText(value.platform) ?? safeText(system?.platform) ?? safeText(system?.architecture);
|
||||
return {
|
||||
...(cpuPercent === undefined ? {} : { cpuPercent }),
|
||||
...(memoryPercent === undefined ? {} : { memoryPercent }),
|
||||
...(maxTemperatureCelsius === undefined ? {} : { maxTemperatureCelsius }),
|
||||
...(version ? { version } : {}),
|
||||
...(platform ? { platform } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -69,6 +106,11 @@ export class InstanceResourceService {
|
||||
readonly instances: InstanceService;
|
||||
readonly sessions: InstanceSessionStore;
|
||||
readonly request: UpstreamSessionClientOptions['request'];
|
||||
readonly ensureSession?: (
|
||||
instanceId: string,
|
||||
origin: string,
|
||||
force?: boolean,
|
||||
) => Promise<void>;
|
||||
},
|
||||
) {}
|
||||
|
||||
@@ -79,19 +121,48 @@ export class InstanceResourceService {
|
||||
]);
|
||||
if (!instance) return {};
|
||||
if (session && session.origin !== instance.origin) return {};
|
||||
const get = (path: '/api/stats' | '/api/sim') =>
|
||||
this.options.request({
|
||||
url: `${instance.origin}${path}`,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
...(session ? { cookie: session.cookie } : {}),
|
||||
},
|
||||
});
|
||||
const [stats, sim] = await Promise.allSettled([get('/api/stats'), get('/api/sim')]);
|
||||
if (!session && this.options.ensureSession) {
|
||||
try {
|
||||
await this.options.ensureSession(instanceId, instance.origin);
|
||||
} catch {
|
||||
// Passwordless and temporarily unavailable credentials still permit anonymous reads.
|
||||
}
|
||||
}
|
||||
const paths = ['/api/stats', '/api/sim', '/api/health'] as const;
|
||||
const readAll = () => {
|
||||
const activeSession = this.options.sessions.sessionFor(instanceId);
|
||||
return Promise.allSettled(
|
||||
paths.map((path) =>
|
||||
this.options.request({
|
||||
url: `${instance.origin}${path}`,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
...(activeSession?.origin === instance.origin
|
||||
? { cookie: activeSession.cookie }
|
||||
: {}),
|
||||
},
|
||||
}),
|
||||
),
|
||||
);
|
||||
};
|
||||
let results = await readAll();
|
||||
const unauthorized = results.some(
|
||||
(result) => result.status === 'fulfilled' && [401, 403].includes(result.value.status),
|
||||
);
|
||||
if (unauthorized && this.options.ensureSession) {
|
||||
try {
|
||||
await this.options.ensureSession(instanceId, instance.origin, true);
|
||||
results = await readAll();
|
||||
} catch {
|
||||
// Return the safe partial result when re-authentication is unavailable.
|
||||
}
|
||||
}
|
||||
const [stats, sim, health] = results;
|
||||
return {
|
||||
...(stats.status === 'fulfilled' ? parseStats(stats.value) : {}),
|
||||
...(sim.status === 'fulfilled' ? parseSim(sim.value) : {}),
|
||||
...(stats?.status === 'fulfilled' ? parseStats(stats.value) : {}),
|
||||
...(sim?.status === 'fulfilled' ? parseSim(sim.value) : {}),
|
||||
...(health?.status === 'fulfilled' ? parseHealth(health.value) : {}),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user