diff --git a/packages/trace-viewer/src/sw/main.ts b/packages/trace-viewer/src/sw/main.ts index 7888aa6a308e6..2f834956114f5 100644 --- a/packages/trace-viewer/src/sw/main.ts +++ b/packages/trace-viewer/src/sw/main.ts @@ -36,16 +36,16 @@ const scopePath = new URL(self.registration.scope).pathname; const loadedTraces = new Map(); -const clientIdToTraceUrls = new Map>(); +const clientIdToTraceUrls = new Map }>(); -async function loadTrace(traceUrl: string, traceFileName: string | null, clientId: string, progress: (done: number, total: number) => undefined): Promise { +async function loadTrace(traceUrl: string, traceFileName: string | null, clientId: string, limit: number | undefined, progress: (done: number, total: number) => undefined): Promise { await gc(); - let set = clientIdToTraceUrls.get(clientId); - if (!set) { - set = new Set(); - clientIdToTraceUrls.set(clientId, set); + let data = clientIdToTraceUrls.get(clientId); + if (!data) { + data = { limit, traceUrls: new Set() }; + clientIdToTraceUrls.set(clientId, data); } - set.add(traceUrl); + data.traceUrls.add(traceUrl); const traceModel = new TraceModel(); try { @@ -97,7 +97,8 @@ async function doFetch(event: FetchEvent): Promise { if (relativePath === '/contexts') { try { - const traceModel = await loadTrace(traceUrl!, url.searchParams.get('traceFileName'), event.clientId, (done: number, total: number) => { + const limit = url.searchParams.has('limit') ? +url.searchParams.get('limit')! : undefined; + const traceModel = await loadTrace(traceUrl!, url.searchParams.get('traceFileName'), event.clientId, limit, (done: number, total: number) => { client.postMessage({ method: 'progress', params: { done, total } }); }); return new Response(JSON.stringify(traceModel!.contextEntries), { @@ -172,12 +173,18 @@ async function gc() { const clients = await self.clients.matchAll(); const usedTraces = new Set(); - for (const [clientId, traceUrls] of clientIdToTraceUrls) { + for (const [clientId, data] of clientIdToTraceUrls) { // @ts-ignore - if (!clients.find(c => c.id === clientId)) + if (!clients.find(c => c.id === clientId)) { clientIdToTraceUrls.delete(clientId); - else - traceUrls.forEach(url => usedTraces.add(url)); + continue; + } + if (data.limit !== undefined) { + const ordered = [...data.traceUrls]; + // Leave the newest requested traces. + data.traceUrls = new Set(ordered.slice(ordered.length - data.limit)); + } + data.traceUrls.forEach(url => usedTraces.add(url)); } for (const traceUrl of loadedTraces.keys()) { diff --git a/packages/trace-viewer/src/ui/embeddedWorkbenchLoader.tsx b/packages/trace-viewer/src/ui/embeddedWorkbenchLoader.tsx index 3500b93b1f38d..b398897975dba 100644 --- a/packages/trace-viewer/src/ui/embeddedWorkbenchLoader.tsx +++ b/packages/trace-viewer/src/ui/embeddedWorkbenchLoader.tsx @@ -65,6 +65,7 @@ export const EmbeddedWorkbenchLoader: React.FunctionComponent = () => { const url = traceURLs[i]; const params = new URLSearchParams(); params.set('trace', url); + params.set('limit', String(traceURLs.length)); const response = await fetch(`contexts?${params.toString()}`); if (!response.ok) { setProcessingErrorMessage((await response.json()).error); diff --git a/packages/trace-viewer/src/ui/recorder/modelContext.tsx b/packages/trace-viewer/src/ui/recorder/modelContext.tsx index 9db52e1964f53..98f450361b3db 100644 --- a/packages/trace-viewer/src/ui/recorder/modelContext.tsx +++ b/packages/trace-viewer/src/ui/recorder/modelContext.tsx @@ -58,6 +58,7 @@ export const ModelProvider: React.FunctionComponent { const params = new URLSearchParams(); params.set('trace', url); + params.set('limit', '1'); const response = await fetch(`contexts?${params.toString()}`); const contextEntries = await response.json() as ContextEntry[]; diff --git a/packages/trace-viewer/src/ui/uiModeTraceView.tsx b/packages/trace-viewer/src/ui/uiModeTraceView.tsx index ed63a2adab240..cf35d89007007 100644 --- a/packages/trace-viewer/src/ui/uiModeTraceView.tsx +++ b/packages/trace-viewer/src/ui/uiModeTraceView.tsx @@ -111,6 +111,7 @@ const outputDirForTestCase = (testCase: reporterTypes.TestCase): string | undefi async function loadSingleTraceFile(url: string): Promise { const params = new URLSearchParams(); params.set('trace', url); + params.set('limit', '1'); const response = await fetch(`contexts?${params.toString()}`); const contextEntries = await response.json() as ContextEntry[]; return new MultiTraceModel(contextEntries); diff --git a/packages/trace-viewer/src/ui/workbenchLoader.tsx b/packages/trace-viewer/src/ui/workbenchLoader.tsx index 19793d4b579ca..72c02a4f6caa6 100644 --- a/packages/trace-viewer/src/ui/workbenchLoader.tsx +++ b/packages/trace-viewer/src/ui/workbenchLoader.tsx @@ -131,6 +131,7 @@ export const WorkbenchLoader: React.FunctionComponent<{ params.set('trace', url); if (uploadedTraceNames.length) params.set('traceFileName', uploadedTraceNames[i]); + params.set('limit', String(traceURLs.length)); const response = await fetch(`contexts?${params.toString()}`); if (!response.ok) { if (!isServer)