fix(trace viewer): limit the number of contexts loaded in sw
UI mode may load many traces, one for each test, in the same service worker. This change introduces an upper limit to the number of traces stored in sw.
This commit is contained in:
parent
29ca54eb38
commit
669ef05940
|
|
@ -36,16 +36,16 @@ const scopePath = new URL(self.registration.scope).pathname;
|
||||||
|
|
||||||
const loadedTraces = new Map<string, { traceModel: TraceModel, snapshotServer: SnapshotServer }>();
|
const loadedTraces = new Map<string, { traceModel: TraceModel, snapshotServer: SnapshotServer }>();
|
||||||
|
|
||||||
const clientIdToTraceUrls = new Map<string, Set<string>>();
|
const clientIdToTraceUrls = new Map<string, { limit: number | undefined, traceUrls: Set<string> }>();
|
||||||
|
|
||||||
async function loadTrace(traceUrl: string, traceFileName: string | null, clientId: string, progress: (done: number, total: number) => undefined): Promise<TraceModel> {
|
async function loadTrace(traceUrl: string, traceFileName: string | null, clientId: string, limit: number | undefined, progress: (done: number, total: number) => undefined): Promise<TraceModel> {
|
||||||
await gc();
|
await gc();
|
||||||
let set = clientIdToTraceUrls.get(clientId);
|
let data = clientIdToTraceUrls.get(clientId);
|
||||||
if (!set) {
|
if (!data) {
|
||||||
set = new Set();
|
data = { limit, traceUrls: new Set() };
|
||||||
clientIdToTraceUrls.set(clientId, set);
|
clientIdToTraceUrls.set(clientId, data);
|
||||||
}
|
}
|
||||||
set.add(traceUrl);
|
data.traceUrls.add(traceUrl);
|
||||||
|
|
||||||
const traceModel = new TraceModel();
|
const traceModel = new TraceModel();
|
||||||
try {
|
try {
|
||||||
|
|
@ -97,7 +97,8 @@ async function doFetch(event: FetchEvent): Promise<Response> {
|
||||||
|
|
||||||
if (relativePath === '/contexts') {
|
if (relativePath === '/contexts') {
|
||||||
try {
|
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 } });
|
client.postMessage({ method: 'progress', params: { done, total } });
|
||||||
});
|
});
|
||||||
return new Response(JSON.stringify(traceModel!.contextEntries), {
|
return new Response(JSON.stringify(traceModel!.contextEntries), {
|
||||||
|
|
@ -179,12 +180,18 @@ async function gc() {
|
||||||
const clients = await self.clients.matchAll();
|
const clients = await self.clients.matchAll();
|
||||||
const usedTraces = new Set<string>();
|
const usedTraces = new Set<string>();
|
||||||
|
|
||||||
for (const [clientId, traceUrls] of clientIdToTraceUrls) {
|
for (const [clientId, data] of clientIdToTraceUrls) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (!clients.find(c => c.id === clientId))
|
if (!clients.find(c => c.id === clientId)) {
|
||||||
clientIdToTraceUrls.delete(clientId);
|
clientIdToTraceUrls.delete(clientId);
|
||||||
else
|
continue;
|
||||||
traceUrls.forEach(url => usedTraces.add(url));
|
}
|
||||||
|
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()) {
|
for (const traceUrl of loadedTraces.keys()) {
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ export const EmbeddedWorkbenchLoader: React.FunctionComponent = () => {
|
||||||
const url = traceURLs[i];
|
const url = traceURLs[i];
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
params.set('trace', url);
|
params.set('trace', url);
|
||||||
|
params.set('limit', String(traceURLs.length));
|
||||||
const response = await fetch(`contexts?${params.toString()}`);
|
const response = await fetch(`contexts?${params.toString()}`);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
setProcessingErrorMessage((await response.json()).error);
|
setProcessingErrorMessage((await response.json()).error);
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ export const ModelProvider: React.FunctionComponent<React.PropsWithChildren<{
|
||||||
async function loadSingleTraceFile(url: string): Promise<{ model: MultiTraceModel, sha1: string }> {
|
async function loadSingleTraceFile(url: string): Promise<{ model: MultiTraceModel, sha1: string }> {
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
params.set('trace', url);
|
params.set('trace', url);
|
||||||
|
params.set('limit', '1');
|
||||||
const response = await fetch(`contexts?${params.toString()}`);
|
const response = await fetch(`contexts?${params.toString()}`);
|
||||||
const contextEntries = await response.json() as ContextEntry[];
|
const contextEntries = await response.json() as ContextEntry[];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,7 @@ const outputDirForTestCase = (testCase: reporterTypes.TestCase): string | undefi
|
||||||
async function loadSingleTraceFile(url: string): Promise<MultiTraceModel> {
|
async function loadSingleTraceFile(url: string): Promise<MultiTraceModel> {
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
params.set('trace', url);
|
params.set('trace', url);
|
||||||
|
params.set('limit', '1');
|
||||||
const response = await fetch(`contexts?${params.toString()}`);
|
const response = await fetch(`contexts?${params.toString()}`);
|
||||||
const contextEntries = await response.json() as ContextEntry[];
|
const contextEntries = await response.json() as ContextEntry[];
|
||||||
return new MultiTraceModel(contextEntries);
|
return new MultiTraceModel(contextEntries);
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,7 @@ export const WorkbenchLoader: React.FunctionComponent<{
|
||||||
params.set('trace', url);
|
params.set('trace', url);
|
||||||
if (uploadedTraceNames.length)
|
if (uploadedTraceNames.length)
|
||||||
params.set('traceFileName', uploadedTraceNames[i]);
|
params.set('traceFileName', uploadedTraceNames[i]);
|
||||||
|
params.set('limit', String(traceURLs.length));
|
||||||
const response = await fetch(`contexts?${params.toString()}`);
|
const response = await fetch(`contexts?${params.toString()}`);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
if (!isServer)
|
if (!isServer)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue