-
Notifications
You must be signed in to change notification settings - Fork 4.8k
fix(trace): survive sw restart #37442
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
| "version": "0.0.0", | ||
| "type": "module", | ||
| "dependencies": { | ||
| "idb-keyval": "^6.2.2", | ||
| "yaml": "^2.6.0" | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,8 @@ | |
| * limitations under the License. | ||
| */ | ||
|
|
||
| import * as idbKeyval from 'idb-keyval'; | ||
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
Sorry, something went wrong. |
||
|
|
||
| import { splitProgress } from './progress'; | ||
| import { unwrapPopoutUrl } from './snapshotRenderer'; | ||
| import { SnapshotServer } from './snapshotServer'; | ||
|
|
@@ -33,11 +35,14 @@ self.addEventListener('activate', function(event: any) { | |
| }); | ||
|
|
||
| const scopePath = new URL(self.registration.scope).pathname; | ||
|
|
||
| const loadedTraces = new Map<string, { traceModel: TraceModel, snapshotServer: SnapshotServer }>(); | ||
|
|
||
| const clientIdToTraceUrls = new Map<string, { limit: number | undefined, traceUrls: Set<string>, traceViewerServer: TraceViewerServer }>(); | ||
|
|
||
| function simulateServiceWorkerRestart() { | ||
| loadedTraces.clear(); | ||
| clientIdToTraceUrls.clear(); | ||
| } | ||
|
|
||
| async function loadTrace(traceUrl: string, traceFileName: string | null, client: any | undefined, limit: number | undefined, progress: (done: number, total: number) => undefined): Promise<TraceModel> { | ||
| await gc(); | ||
| const clientId = client?.id ?? ''; | ||
|
|
@@ -49,6 +54,7 @@ async function loadTrace(traceUrl: string, traceFileName: string | null, client: | |
| clientIdToTraceUrls.set(clientId, data); | ||
| } | ||
| data.traceUrls.add(traceUrl); | ||
| await saveClientIdParams(); | ||
|
|
||
| const traceModel = new TraceModel(); | ||
| try { | ||
|
|
@@ -101,6 +107,10 @@ async function doFetch(event: FetchEvent): Promise<Response> { | |
| await gc(); | ||
| return new Response(null, { status: 200 }); | ||
| } | ||
| if (relativePath === '/restartServiceWorker') { | ||
| simulateServiceWorkerRestart(); | ||
| return new Response(null, { status: 200 }); | ||
| } | ||
|
|
||
| const traceUrl = url.searchParams.get('trace'); | ||
|
|
||
|
|
@@ -122,6 +132,16 @@ async function doFetch(event: FetchEvent): Promise<Response> { | |
| } | ||
| } | ||
|
|
||
| if (!clientIdToTraceUrls.has(event.clientId)) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the 'trace/snapshot/' client this will always be true. |
||
| // Service worker was restarted upon subresource fetch. | ||
| // It was stopped because ping did not keep it alive since the tab itself was throttled. | ||
| const params = await loadClientIdParams(event.clientId); | ||
| if (params) { | ||
| for (const traceUrl of params.traceUrls) | ||
| await loadTrace(traceUrl, null, client, params.limit, () => {}); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Maybe move |
||
| } | ||
| } | ||
|
|
||
| if (relativePath.startsWith('/snapshotInfo/')) { | ||
| const { snapshotServer } = loadedTraces.get(traceUrl!) || {}; | ||
| if (!snapshotServer) | ||
|
|
@@ -221,6 +241,36 @@ async function gc() { | |
| if (!usedTraces.has(traceUrl)) | ||
| loadedTraces.delete(traceUrl); | ||
| } | ||
|
|
||
| await saveClientIdParams(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Saving here is troublesome: When we re-open the browser tab, the service worker starts again, and the So, I suggest to either only call |
||
| } | ||
|
|
||
| // Persist clientIdToTraceUrls to localStorage to avoid losing it when the service worker is restarted. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Technically IndexDB !== localStorage |
||
| async function saveClientIdParams() { | ||
| const serialized: Record<string, { | ||
| limit: number | undefined, | ||
| traceUrls: string[] | ||
| }> = {}; | ||
| for (const [clientId, data] of clientIdToTraceUrls) { | ||
| serialized[clientId] = { | ||
| limit: data.limit, | ||
| traceUrls: [...data.traceUrls] | ||
| }; | ||
| } | ||
|
|
||
| const newValue = JSON.stringify(serialized); | ||
| const oldValue = await idbKeyval.get('clientIdToTraceUrls'); | ||
| if (newValue === oldValue) | ||
| return; | ||
| idbKeyval.set('clientIdToTraceUrls', newValue); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we want to |
||
| } | ||
|
|
||
| async function loadClientIdParams(clientId: string): Promise<{ limit: number | undefined, traceUrls: string[] } | undefined> { | ||
| const serialized = await idbKeyval.get('clientIdToTraceUrls') as string | undefined; | ||
| if (!serialized) | ||
| return; | ||
| const deserialized = JSON.parse(serialized); | ||
| return deserialized[clientId]; | ||
| } | ||
|
|
||
| // @ts-ignore | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unpacked Size
928 kB
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sw.bundle.js
before
220990
after
223446