mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Frontend o11y: Load SharedWorkers for crash detection (#96673)
* Load SharedWorkers from blob
* Fix typo
* Update docs
* Add more docs
* Simplify extending CorsSharedWorker
* Revert "Simplify extending CorsSharedWorker"
This reverts commit 1603e5f02f
.
* Simplify extending CorsSharedWorker
* Remove ts-ignore
* Update betterer and add docs
* Update public/app/core/crash/index.ts
Co-authored-by: Sven Grossmann <sven.grossmann@grafana.com>
* Update public/app/core/utils/CorsSharedWorker.ts
Co-authored-by: Sven Grossmann <sven.grossmann@grafana.com>
* Update public/app/core/crash/index.ts
Co-authored-by: Sven Grossmann <sven.grossmann@grafana.com>
* Update public/app/core/utils/CorsSharedWorker.ts
Co-authored-by: Sven Grossmann <sven.grossmann@grafana.com>
* Simplify getting scriptsBasePathUrl
* Disable linting for SharedWorker type assertion
---------
Co-authored-by: Sven Grossmann <sven.grossmann@grafana.com>
This commit is contained in:
parent
5f1fae8efd
commit
60f9ff0a07
@ -3,8 +3,10 @@ import { BaseStateReport } from 'crashme/dist/types';
|
||||
import { nanoid } from 'nanoid';
|
||||
|
||||
import { config, createMonitoringLogger } from '@grafana/runtime';
|
||||
import { CorsWorker as Worker } from 'app/core/utils/CorsWorker';
|
||||
|
||||
import { contextSrv } from '../services/context_srv';
|
||||
import { CorsSharedWorker as SharedWorker, sharedWorkersSupported } from '../utils/CorsSharedWorker';
|
||||
|
||||
import { isChromePerformance, prepareContext } from './crash.utils';
|
||||
|
||||
@ -30,6 +32,10 @@ interface GrafanaCrashReport extends BaseStateReport {
|
||||
}
|
||||
|
||||
export function initializeCrashDetection() {
|
||||
if (!sharedWorkersSupported()) {
|
||||
return;
|
||||
}
|
||||
|
||||
initCrashDetection<GrafanaCrashReport>({
|
||||
id: nanoid(5),
|
||||
|
||||
@ -39,8 +45,18 @@ export function initializeCrashDetection() {
|
||||
return new Worker(new URL('./client.worker', import.meta.url));
|
||||
},
|
||||
|
||||
createDetectorWorker(): SharedWorker {
|
||||
return new SharedWorker(new URL('./detector.worker', import.meta.url));
|
||||
/**
|
||||
* There are limitations that require us to manually assert the type here.
|
||||
* 1) Webpack uses static code analysis to create a new entry point for a SharedWorker.
|
||||
* It requies constructing an object with exact syntax new SharedWorker(...) (https://webpack.js.org/guides/web-workers/)
|
||||
* 2) Some browsers may not support SharedWorkers hence we cannot extend CorsSharedWorker like CorsWorker and
|
||||
* window.SharedWorker needs to be referenced during runtime only if it is supported (https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker)
|
||||
*
|
||||
* We guarantee the type assertion is correct by returning a SharedWorker in CorsSharedWorker constructor.
|
||||
*/
|
||||
createDetectorWorker() {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
return new SharedWorker(new URL('./detector.worker', import.meta.url)) as globalThis.SharedWorker;
|
||||
},
|
||||
|
||||
reportCrash: async (report) => {
|
||||
|
33
public/app/core/utils/CorsSharedWorker.ts
Normal file
33
public/app/core/utils/CorsSharedWorker.ts
Normal file
@ -0,0 +1,33 @@
|
||||
// Almost identical to CorsWorker.ts. Main difference being it allows loading a SharedWorker if browser supports it
|
||||
|
||||
export function sharedWorkersSupported() {
|
||||
return typeof window.SharedWorker !== 'undefined';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creating CorsSharedWorker should be called only if sharedWorkersSupported() is truthy
|
||||
*/
|
||||
export class CorsSharedWorker {
|
||||
constructor(url: URL, options?: WorkerOptions) {
|
||||
if (!sharedWorkersSupported()) {
|
||||
throw new Error('SharedWorker is not supported');
|
||||
}
|
||||
// by default, worker inherits HTML document's location and pathname which leads to wrong public path value
|
||||
// the CorsWorkerPlugin will override it with the value based on the initial worker chunk, ie.
|
||||
// initial worker chunk: http://host.com/cdn/scripts/worker-123.js
|
||||
// resulting public path: http://host.com/cdn/scripts
|
||||
|
||||
const scriptUrl = url.toString();
|
||||
const scriptsBasePathUrl = new URL('.', url).toString();
|
||||
|
||||
const importScripts = `importScripts('${scriptUrl}');`;
|
||||
const objectURL = URL.createObjectURL(
|
||||
new Blob([`__webpack_worker_public_path__ = '${scriptsBasePathUrl}'; ${importScripts}`], {
|
||||
type: 'application/javascript',
|
||||
})
|
||||
);
|
||||
const worker = new SharedWorker(objectURL, options);
|
||||
URL.revokeObjectURL(objectURL);
|
||||
return worker;
|
||||
}
|
||||
}
|
@ -7,9 +7,7 @@ export class CorsWorker extends window.Worker {
|
||||
// resulting public path: http://host.com/cdn/scripts
|
||||
|
||||
const scriptUrl = url.toString();
|
||||
const urlParts = scriptUrl.split('/');
|
||||
urlParts.pop();
|
||||
const scriptsBasePathUrl = `${urlParts.join('/')}/`;
|
||||
const scriptsBasePathUrl = new URL('.', url).toString();
|
||||
|
||||
const importScripts = `importScripts('${scriptUrl}');`;
|
||||
const objectURL = URL.createObjectURL(
|
||||
|
Loading…
Reference in New Issue
Block a user