mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-16 14:16:16 -08:00
* docs(performance): plan Xtream benchmark * feat(xtream-mock-server): add deterministic 100k fixture * style(xtream-mock-server): apply repository formatting * fix(xtream-mock-server): harden performance fixture data * feat(xtream-mock-server): add performance control plane * docs(performance): correct Xtream capture plan * fix(xtream-mock-server): harden performance controls * fix(xtream-mock-server): harden control lifecycle * feat(performance): add Xtream preload markers * feat(performance): trace Xtream main phases * feat(performance): mark Xtream store publications * feat(performance): trace Xtream database phases * feat(performance): trace Xtream delete cancellation * feat(performance): capture Xtream phase attribution * feat(performance): mark Sources Xtream refresh * test(performance): define Xtream benchmark evidence contracts * test(performance): add Xtream benchmark runner * test(performance): surface failure evidence writes * test(performance): align database read clock * test(performance): preserve capture failure contracts
86 lines
3.0 KiB
TypeScript
86 lines
3.0 KiB
TypeScript
import type { WorkerRequestPerformanceMetrics } from './m3u-refresh-cancellation-contract';
|
|
import type {
|
|
XtreamIpcAttributionSpan,
|
|
XtreamPhaseAttributionInput,
|
|
} from './xtream-phase-attribution';
|
|
import { xtreamWorkerOperationForIpcMethod } from './xtream-ipc-worker-identity-binding';
|
|
|
|
interface ProducerIdentity {
|
|
readonly ipcCallId: number;
|
|
readonly sourceEpochMs: number;
|
|
}
|
|
|
|
export function bindFixtureIpcWorkerIdentities(
|
|
input: XtreamPhaseAttributionInput,
|
|
requests: readonly WorkerRequestPerformanceMetrics[]
|
|
): {
|
|
readonly phaseCapture: XtreamPhaseAttributionInput;
|
|
readonly requests: readonly WorkerRequestPerformanceMetrics[];
|
|
} {
|
|
const identities = new Map<
|
|
WorkerRequestPerformanceMetrics,
|
|
ProducerIdentity
|
|
>();
|
|
const methods = new Set(
|
|
input.ipcSpans
|
|
.filter(({ boundary }) => boundary === 'request')
|
|
.map(({ method }) => method)
|
|
.filter(
|
|
(method) => xtreamWorkerOperationForIpcMethod(method) !== null
|
|
)
|
|
);
|
|
for (const method of methods) {
|
|
const operation = xtreamWorkerOperationForIpcMethod(method);
|
|
if (operation === null) fixtureError();
|
|
const calls = requestSpans(input.ipcSpans, method);
|
|
const workers = requests
|
|
.filter((request) => request.operation === operation)
|
|
.sort(
|
|
(left, right) =>
|
|
Number(left.requestReceivedEpochMs) -
|
|
Number(right.requestReceivedEpochMs) ||
|
|
String(left.requestId).localeCompare(
|
|
String(right.requestId)
|
|
)
|
|
);
|
|
if (calls.length !== workers.length) fixtureError();
|
|
calls.forEach((call, index) => {
|
|
const worker = workers[index];
|
|
if (
|
|
!worker ||
|
|
call.outcome !== (worker.success ? 'success' : 'error') ||
|
|
worker.requestReceivedEpochMs === null ||
|
|
call.sourceEpochMs > worker.requestReceivedEpochMs
|
|
) {
|
|
fixtureError();
|
|
}
|
|
identities.set(worker, {
|
|
ipcCallId: call.ipcCallId,
|
|
sourceEpochMs: call.sourceEpochMs,
|
|
});
|
|
});
|
|
}
|
|
const bound = requests.map((request) => {
|
|
const identity = identities.get(request);
|
|
if (identity) return { ...request, ...identity };
|
|
if (request.ipcCallId !== null || request.sourceEpochMs !== null) {
|
|
fixtureError();
|
|
}
|
|
return request;
|
|
});
|
|
return { phaseCapture: input, requests: bound };
|
|
}
|
|
|
|
function requestSpans(
|
|
spans: readonly XtreamIpcAttributionSpan[],
|
|
method: string
|
|
): readonly XtreamIpcAttributionSpan[] {
|
|
return spans
|
|
.filter((span) => span.boundary === 'request' && span.method === method)
|
|
.sort((left, right) => left.ipcCallId - right.ipcCallId);
|
|
}
|
|
|
|
function fixtureError(): never {
|
|
throw new Error('invalid Xtream IPC worker identity fixture');
|
|
}
|