Add more SW debug

Use first crypto worker as is
This commit is contained in:
Eduard Kuzmenko 2022-08-24 17:01:28 +02:00
parent 4c0f014362
commit dde531545a
5 changed files with 51 additions and 27 deletions

View File

@ -5,6 +5,7 @@
*/ */
import App from '../../config/app'; import App from '../../config/app';
import {MOUNT_CLASS_TO} from '../../config/debug';
import callbackify from '../../helpers/callbackify'; import callbackify from '../../helpers/callbackify';
import deferredPromise, {CancellablePromise} from '../../helpers/cancellablePromise'; import deferredPromise, {CancellablePromise} from '../../helpers/cancellablePromise';
import cryptoMessagePort from '../crypto/cryptoMessagePort'; import cryptoMessagePort from '../crypto/cryptoMessagePort';
@ -53,16 +54,21 @@ export class AppManagersManager {
this.cryptoPortPromise?.resolve(); this.cryptoPortPromise?.resolve();
}); });
port.addEventListener('createProxyWorkerURLs', (blob) => { port.addEventListener('createProxyWorkerURLs', ({originalUrl, blob}) => {
const length = this.cryptoWorkersURLs.length; let length = this.cryptoWorkersURLs.length;
if(!length) {
this.cryptoWorkersURLs.push(originalUrl);
++length;
}
const maxLength = App.cryptoWorkers; const maxLength = App.cryptoWorkers;
if(length) { if(length === maxLength) {
return this.cryptoWorkersURLs; return this.cryptoWorkersURLs;
} }
const newURLs = new Array(maxLength - length).fill(undefined).map(() => URL.createObjectURL(blob)); const newURLs = new Array(maxLength - length).fill(undefined).map(() => URL.createObjectURL(blob));
this.cryptoWorkersURLs.push(...newURLs); this.cryptoWorkersURLs.push(...newURLs);
return newURLs; return this.cryptoWorkersURLs;
}); });
} }
@ -85,4 +91,5 @@ export class AppManagersManager {
} }
const appManagersManager = new AppManagersManager(); const appManagersManager = new AppManagersManager();
MOUNT_CLASS_TO && (MOUNT_CLASS_TO.appManagersManager = appManagersManager);
export default appManagersManager; export default appManagersManager;

View File

@ -31,7 +31,7 @@ export default class MTProtoMessagePort<Master extends boolean = true> extends S
cryptoPort: (payload: void, source: MessageEventSource, event: MessageEvent) => void, cryptoPort: (payload: void, source: MessageEventSource, event: MessageEvent) => void,
createObjectURL: (blob: Blob) => string, createObjectURL: (blob: Blob) => string,
tabState: (payload: TabState, source: MessageEventSource) => void, tabState: (payload: TabState, source: MessageEventSource) => void,
createProxyWorkerURLs: (blob: Blob) => string[], createProxyWorkerURLs: (payload: {originalUrl: string, blob: Blob}) => string[],
} & MTProtoBroadcastEvent, { } & MTProtoBroadcastEvent, {
convertWebp: (payload: {fileName: string, bytes: Uint8Array}) => Promise<Uint8Array>, convertWebp: (payload: {fileName: string, bytes: Uint8Array}) => Promise<Uint8Array>,
convertOpus: (payload: {fileName: string, bytes: Uint8Array}) => Promise<Uint8Array>, convertOpus: (payload: {fileName: string, bytes: Uint8Array}) => Promise<Uint8Array>,

View File

@ -353,11 +353,11 @@ class ApiManagerProxy extends MTProtoMessagePort {
originals.forEach((w) => window[w.name as any] = w as any); originals.forEach((w) => window[w.name as any] = w as any);
const blob = await get((worker as any).url); const originalUrl = (worker as any).url;
const urlsPromise = await this.invoke('createProxyWorkerURLs', blob);
const workers = urlsPromise.map((url) => { const createWorker = (url: string) => new constructor(url, {type: 'module'});
return new (IS_SHARED_WORKER_SUPPORTED ? SharedWorker : Worker)(url, {type: 'module'}); const attachWorkerToPort = (worker: SharedWorker | Worker) => this.attachWorkerToPort(worker, cryptoMessagePort, 'crypto');
}); const constructor = IS_SHARED_WORKER_SUPPORTED ? SharedWorker : Worker;
// let cryptoWorkers = workers.length; // let cryptoWorkers = workers.length;
cryptoMessagePort.addEventListener('port', (payload, source, event) => { cryptoMessagePort.addEventListener('port', (payload, source, event) => {
@ -375,9 +375,13 @@ class ApiManagerProxy extends MTProtoMessagePort {
// }); // });
}); });
workers.forEach((worker) => { const firstWorker = createWorker(originalUrl);
this.attachWorkerToPort(worker, cryptoMessagePort, 'crypto'); attachWorkerToPort(firstWorker);
});
const blob = await get(originalUrl);
const urlsPromise = await this.invoke('createProxyWorkerURLs', {originalUrl, blob});
const workers = urlsPromise.slice(1).map(createWorker);
workers.forEach(attachWorkerToPort);
} }
// #if !MTPROTO_SW // #if !MTPROTO_SW

View File

@ -5,6 +5,7 @@
*/ */
import DEBUG from '../../config/debug'; import DEBUG from '../../config/debug';
import tabId from '../../config/tabId';
import ctx from '../../environment/ctx'; import ctx from '../../environment/ctx';
import indexOfAndSplice from '../../helpers/array/indexOfAndSplice'; import indexOfAndSplice from '../../helpers/array/indexOfAndSplice';
import {IS_WORKER} from '../../helpers/context'; import {IS_WORKER} from '../../helpers/context';
@ -127,7 +128,9 @@ export default class SuperMessagePort<
protected onPortDisconnect: (source: MessageEventSource) => void; protected onPortDisconnect: (source: MessageEventSource) => void;
// protected onPortConnect: (source: MessageEventSource) => void; // protected onPortConnect: (source: MessageEventSource) => void;
constructor(logSuffix?: string) { protected resolveLocks: Map<SendPort, () => void>;
constructor(protected logSuffix?: string) {
super(false); super(false);
this.listenPorts = []; this.listenPorts = [];
@ -138,19 +141,7 @@ export default class SuperMessagePort<
this.pending = new Map(); this.pending = new Map();
this.log = logger('MP' + (logSuffix ? '-' + logSuffix : '')); this.log = logger('MP' + (logSuffix ? '-' + logSuffix : ''));
this.debug = DEBUG; this.debug = DEBUG;
this.resolveLocks = new Map();
if(typeof(window) !== 'undefined') {
if('locks' in navigator) {
const id = 'lock-' + Date.now() + (Math.random() * 0xFFFF | 0);
navigator.locks.request(id, () => new Promise(() => {}));
this.pushTask(this.createTask('lock', id));
} else {
window.addEventListener('beforeunload', () => {
const task = this.createTask('close', undefined);
this.postMessage(undefined, task);
});
}
}
this.processTaskMap = { this.processTaskMap = {
result: this.processResultTask, result: this.processResultTask,
@ -193,6 +184,22 @@ export default class SuperMessagePort<
// const task = this.createTask('open', undefined); // const task = this.createTask('open', undefined);
// this.postMessage(port, task); // this.postMessage(port, task);
if(typeof(window) !== 'undefined') {
if('locks' in navigator) {
const id = ['lock', tabId, this.logSuffix || '', Math.random() * 0x7FFFFFFF | 0].join('-');
this.log.warn('created lock', id);
const promise = new Promise<void>((resolve) => this.resolveLocks.set(port, resolve))
.then(() => this.resolveLocks.delete(port));
navigator.locks.request(id, () => promise);
this.pushTask(this.createTask('lock', id));
} else {
window.addEventListener('beforeunload', () => {
const task = this.createTask('close', undefined);
this.postMessage(undefined, task);
});
}
}
this.releasePending(); this.releasePending();
} }
@ -244,6 +251,9 @@ export default class SuperMessagePort<
this.onPortDisconnect?.(port as any); this.onPortDisconnect?.(port as any);
const resolveLock = this.resolveLocks.get(port as SendPort);
resolveLock?.();
const error = makeError('PORT_DISCONNECTED'); const error = makeError('PORT_DISCONNECTED');
for(const id in this.awaiting) { for(const id in this.awaiting) {
const task = this.awaiting[id]; const task = this.awaiting[id];

View File

@ -48,6 +48,7 @@ const onWindowConnected = (source: WindowClient) => {
return; return;
} }
log('windows', Array.from(connectedWindows));
sendMessagePortIfNeeded(source); sendMessagePortIfNeeded(source);
connectedWindows.add(source.id); connectedWindows.add(source.id);
}; };
@ -85,8 +86,10 @@ getWindowClients().then((windowClients) => {
const connectedWindows: Set<string> = new Set(); const connectedWindows: Set<string> = new Set();
(self as any).connectedWindows = connectedWindows; (self as any).connectedWindows = connectedWindows;
listenMessagePort(serviceMessagePort, undefined, (source) => { listenMessagePort(serviceMessagePort, undefined, (source) => {
log('something has disconnected', source);
const isWindowClient = source instanceof WindowClient; const isWindowClient = source instanceof WindowClient;
if(!isWindowClient || !connectedWindows.has(source.id)) { if(!isWindowClient || !connectedWindows.has(source.id)) {
log.warn('it is not a window');
return; return;
} }