Workaround for a disconnected worker on iOS

This commit is contained in:
Alexander Zinchuk 2021-08-19 03:16:39 +03:00
parent 49e593d291
commit 4024cd1585
3 changed files with 41 additions and 1 deletions

View File

@ -4,6 +4,7 @@ import { WorkerMessageEvent, ThenArg, OriginRequest } from './types';
import { DEBUG } from '../../../config';
import generateIdFor from '../../../util/generateIdFor';
import { pause } from '../../../util/schedulers';
type RequestStates = {
messageId: string;
@ -12,6 +13,9 @@ type RequestStates = {
callback?: AnyToVoidFunction;
};
const HEALTH_CHECK_TIMEOUT = 1000; // 1 sec
const HEALTH_CHECK_MIN_DELAY = 5 * 1000; // 5 sec
let worker: Worker;
const requestStates = new Map<string, RequestStates>();
const requestStatesByCallback = new Map<AnyToVoidFunction, RequestStates>();
@ -27,6 +31,10 @@ export function initApi(onUpdate: OnApiUpdate, initialArgs: ApiInitialArgs) {
worker = new Worker(new URL('./worker.ts', import.meta.url));
subscribeToWorker(onUpdate);
if (initialArgs.platform === 'iOS') {
setupIosHealthCheck();
}
}
return makeRequest({
@ -104,7 +112,7 @@ function makeRequest(message: OriginRequest) {
Object.assign(requestState, { resolve, reject });
});
if (typeof payload.args[1] === 'function') {
if (('args' in payload) && typeof payload.args[1] === 'function') {
const callback = payload.args.pop() as AnyToVoidFunction;
requestState.callback = callback;
requestStatesByCallback.set(callback, requestState);
@ -125,3 +133,24 @@ function makeRequest(message: OriginRequest) {
return promise;
}
const startedAt = Date.now();
// Workaround for iOS sometimes stops interacting with worker
function setupIosHealthCheck() {
window.addEventListener('focus', async () => {
try {
await Promise.race([
makeRequest({ type: 'ping' }),
pause(HEALTH_CHECK_TIMEOUT).then(() => Promise.reject(new Error('HEALTH_CHECK_TIMEOUT'))),
]);
} catch (err) {
// eslint-disable-next-line no-console
console.error(err);
if (Date.now() - startedAt >= HEALTH_CHECK_MIN_DELAY) {
window.location.reload();
}
}
});
}

View File

@ -33,6 +33,9 @@ export type OriginRequest = {
messageId?: string;
name: keyof Methods;
args: MethodArgs<keyof Methods>;
} | {
type: 'ping';
messageId?: string;
};
export type OriginMessageData = OriginRequest | {

View File

@ -81,6 +81,14 @@ onmessage = async (message: OriginMessageEvent) => {
cancelApiProgress(callback);
}
break;
}
case 'ping': {
sendToOrigin({
type: 'methodResponse',
messageId: data.messageId!,
});
break;
}
}