mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 09:01:03 -08:00
fix(perf): exclude profiler flush from cancel latency
This commit is contained in:
1 parent
8bafd62932
commit
df7eee7e52
3 files changed
+46
-22
No files matched your search
@@ -178,6 +178,20 @@ async function executeRefresh(
|
||||
|
||||
checkpoint(payload);
|
||||
return playlist;
|
||||
} catch (error) {
|
||||
if (error instanceof Error && error.name === 'AbortError') {
|
||||
emitEvent(payload, {
|
||||
status: 'cancelled',
|
||||
phase: 'parsing',
|
||||
});
|
||||
} else {
|
||||
emitEvent(payload, {
|
||||
status: 'error',
|
||||
phase: payload.url ? 'fetching' : 'reading-file',
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
}
|
||||
throw error;
|
||||
} finally {
|
||||
releaseActiveRefresh(payload.operationId, activeRefresh);
|
||||
}
|
||||
@@ -219,22 +233,6 @@ parentPort.on(
|
||||
});
|
||||
} else {
|
||||
const error = execution.error;
|
||||
if (error instanceof Error && error.name === 'AbortError') {
|
||||
emitEvent(payload, {
|
||||
status: 'cancelled',
|
||||
phase: 'parsing',
|
||||
});
|
||||
} else {
|
||||
emitEvent(payload, {
|
||||
status: 'error',
|
||||
phase: payload.url ? 'fetching' : 'reading-file',
|
||||
error:
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: String(error),
|
||||
});
|
||||
}
|
||||
|
||||
postMessage({
|
||||
type: 'response',
|
||||
success: false,
|
||||
|
||||
@@ -50,7 +50,13 @@ function createParentPortHarness<TIncoming, TOutgoing>() {
|
||||
};
|
||||
}
|
||||
|
||||
function mockPerformanceCapture(armGate: ArmGate): void {
|
||||
function mockPerformanceCapture(
|
||||
armGate: ArmGate,
|
||||
failureGates?: {
|
||||
readonly observed: ArmGate;
|
||||
readonly profilingFinished: ArmGate;
|
||||
}
|
||||
): void {
|
||||
jest.doMock('./worker-performance-capture', () => ({
|
||||
armWorkerPerformanceCapture: jest.fn(() => armGate.promise),
|
||||
executeWithWorkerPerformanceCapture: jest.fn(
|
||||
@@ -63,6 +69,8 @@ function mockPerformanceCapture(armGate: ArmGate): void {
|
||||
success: true,
|
||||
};
|
||||
} catch (error) {
|
||||
failureGates?.observed.release();
|
||||
await failureGates?.profilingFinished.promise;
|
||||
return {
|
||||
error,
|
||||
performance: undefined,
|
||||
@@ -86,12 +94,17 @@ describe('worker cancellation while performance capture arms', () => {
|
||||
|
||||
it('cancels playlist work before file access when cancel arrives during arming', async () => {
|
||||
const armGate = createArmGate();
|
||||
const profilingFinished = createArmGate();
|
||||
const failureObserved = createArmGate();
|
||||
const port = createParentPortHarness<
|
||||
PlaylistRefreshWorkerIncomingMessage,
|
||||
PlaylistRefreshWorkerMessage<unknown>
|
||||
>();
|
||||
const readFile = jest.fn().mockResolvedValue('#EXTM3U');
|
||||
mockPerformanceCapture(armGate);
|
||||
mockPerformanceCapture(armGate, {
|
||||
observed: failureObserved,
|
||||
profilingFinished,
|
||||
});
|
||||
jest.doMock('worker_threads', () => ({
|
||||
parentPort: port.parentPort,
|
||||
}));
|
||||
@@ -122,9 +135,25 @@ describe('worker cancellation while performance capture arms', () => {
|
||||
operationId: 'refresh-1',
|
||||
});
|
||||
armGate.release();
|
||||
await failureObserved.promise;
|
||||
|
||||
const cancelledBeforeProfilingFinished =
|
||||
port.postMessage.mock.calls.some(
|
||||
([message]) =>
|
||||
message.type === 'event' &&
|
||||
message.event.status === 'cancelled'
|
||||
);
|
||||
const responseBeforeProfilingFinished =
|
||||
port.postMessage.mock.calls.some(
|
||||
([message]) => message.type === 'response'
|
||||
);
|
||||
|
||||
profilingFinished.release();
|
||||
await requestPromise;
|
||||
|
||||
expect(readFile).not.toHaveBeenCalled();
|
||||
expect(cancelledBeforeProfilingFinished).toBe(true);
|
||||
expect(responseBeforeProfilingFinished).toBe(false);
|
||||
expect(port.postMessage).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
event: expect.objectContaining({
|
||||
|
||||
@@ -37,7 +37,7 @@ describe('worker performance integration order', () => {
|
||||
expect(handler).not.toContain('requestQueue');
|
||||
});
|
||||
|
||||
it('finishes playlist profiling before cancellation/error events and response serialization', () => {
|
||||
it('keeps playlist response serialization after profiling completion', () => {
|
||||
const source = readWorkerSource('playlist-refresh.worker.ts');
|
||||
const handler = source.slice(source.lastIndexOf('parentPort.on('));
|
||||
const executionIndex = handler.indexOf(
|
||||
@@ -46,9 +46,6 @@ describe('worker performance integration order', () => {
|
||||
|
||||
expect(executionIndex).toBeGreaterThanOrEqual(0);
|
||||
expect(handler).not.toContain('finishWorkerPerformanceCapture');
|
||||
expect(executionIndex).toBeLessThan(
|
||||
handler.indexOf('emitEvent', executionIndex)
|
||||
);
|
||||
expect(executionIndex).toBeLessThan(
|
||||
handler.indexOf('serializeError', executionIndex)
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user