mirror of https://github.com/gorhill/uBlock.git
Harden diff-updater against unexpected errors
The diff-updater worker will terminate upon unexpected error, in order to avoid a stalled updater.
This commit is contained in:
parent
a45e33cd7a
commit
2344cbdeca
|
@ -1214,6 +1214,13 @@ async function diffUpdater() {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
let pendingOps = 0;
|
let pendingOps = 0;
|
||||||
const bc = new globalThis.BroadcastChannel('diffUpdater');
|
const bc = new globalThis.BroadcastChannel('diffUpdater');
|
||||||
|
const terminate = error => {
|
||||||
|
worker.terminate();
|
||||||
|
bc.close();
|
||||||
|
resolve();
|
||||||
|
if ( typeof error !== 'string' ) { return; }
|
||||||
|
ubolog(`Diff updater: terminate because ${error}`);
|
||||||
|
};
|
||||||
bc.onmessage = ev => {
|
bc.onmessage = ev => {
|
||||||
const data = ev.data;
|
const data = ev.data;
|
||||||
if ( data.what === 'ready' ) {
|
if ( data.what === 'ready' ) {
|
||||||
|
@ -1226,6 +1233,10 @@ async function diffUpdater() {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if ( data.what === 'broken' ) {
|
||||||
|
terminate(data.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if ( data.status === 'needtext' ) {
|
if ( data.status === 'needtext' ) {
|
||||||
ubolog('Diff updater: need text for', data.name);
|
ubolog('Diff updater: need text for', data.name);
|
||||||
assetCacheRead(data.name).then(result => {
|
assetCacheRead(data.name).then(result => {
|
||||||
|
@ -1236,7 +1247,7 @@ async function diffUpdater() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ( data.status === 'updated' ) {
|
if ( data.status === 'updated' ) {
|
||||||
ubolog(`Diff updater: successfully patched ${data.name} using ${data.diffURL}`);
|
ubolog(`Diff updater: successfully patched ${data.name} using ${data.patchURL} (${data.patchSize})`);
|
||||||
const metadata = extractMetadataFromList(data.text, [
|
const metadata = extractMetadataFromList(data.text, [
|
||||||
'Last-Modified',
|
'Last-Modified',
|
||||||
'Expires',
|
'Expires',
|
||||||
|
@ -1262,9 +1273,7 @@ async function diffUpdater() {
|
||||||
}
|
}
|
||||||
if ( pendingOps !== 0 ) { return; }
|
if ( pendingOps !== 0 ) { return; }
|
||||||
ubolog('Diff updater: cycle complete');
|
ubolog('Diff updater: cycle complete');
|
||||||
worker.terminate();
|
terminate();
|
||||||
bc.close();
|
|
||||||
resolve();
|
|
||||||
};
|
};
|
||||||
const worker = new Worker('js/diff-updater.js');
|
const worker = new Worker('js/diff-updater.js');
|
||||||
});
|
});
|
||||||
|
|
|
@ -173,17 +173,22 @@ async function fetchPatchDetailsFromCDNs(assetDetails) {
|
||||||
if ( Array.isArray(cdnURLs) === false ) { return null; }
|
if ( Array.isArray(cdnURLs) === false ) { return null; }
|
||||||
if ( cdnURLs.length === 0 ) { return null; }
|
if ( cdnURLs.length === 0 ) { return null; }
|
||||||
for ( const cdnURL of suffleArray(cdnURLs) ) {
|
for ( const cdnURL of suffleArray(cdnURLs) ) {
|
||||||
const diffURL = resolveURL(patchPath, cdnURL);
|
const patchURL = resolveURL(patchPath, cdnURL);
|
||||||
if ( diffURL === undefined ) { continue; }
|
if ( patchURL === undefined ) { continue; }
|
||||||
const response = await fetch(diffURL).catch(reason => {
|
const response = await fetch(patchURL).catch(reason => {
|
||||||
console.error(reason);
|
console.error(reason);
|
||||||
});
|
});
|
||||||
if ( response === undefined ) { continue; }
|
if ( response === undefined ) { continue; }
|
||||||
if ( response.ok !== true ) { continue; }
|
if ( response.ok !== true ) { continue; }
|
||||||
const patchText = await response.text();
|
const patchText = await response.text();
|
||||||
|
if ( patchText.length === 0 ) { continue; }
|
||||||
const patchDetails = parsePatch(patchText);
|
const patchDetails = parsePatch(patchText);
|
||||||
if ( patchDetails === undefined ) { continue; }
|
if ( patchDetails === undefined ) { continue; }
|
||||||
return { diffURL, patchDetails };
|
return {
|
||||||
|
patchURL,
|
||||||
|
patchSize: `${(patchText.length / 1000).toFixed(1)} KB`,
|
||||||
|
patchDetails,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -202,11 +207,12 @@ async function fetchPatchDetails(assetDetails) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchAndApplyAllPatches(assetDetails) {
|
async function fetchAndApplyAllPatches(assetDetails) {
|
||||||
const { diffURL, patchDetails } = await fetchPatchDetails(assetDetails);
|
const patchData = await fetchPatchDetails(assetDetails);
|
||||||
if ( patchDetails === null ) {
|
if ( patchData === null ) {
|
||||||
assetDetails.error = 'nopatch';
|
assetDetails.error = 'nopatch';
|
||||||
return assetDetails;
|
return assetDetails;
|
||||||
}
|
}
|
||||||
|
const { patchDetails } = patchData;
|
||||||
const diffDetails = patchDetails.get(assetDetails.diffName);
|
const diffDetails = patchDetails.get(assetDetails.diffName);
|
||||||
if ( diffDetails === undefined ) {
|
if ( diffDetails === undefined ) {
|
||||||
assetDetails.error = 'nodiff';
|
assetDetails.error = 'nodiff';
|
||||||
|
@ -219,7 +225,8 @@ async function fetchAndApplyAllPatches(assetDetails) {
|
||||||
const outcome = await applyPatchAndValidate(assetDetails, diffDetails);
|
const outcome = await applyPatchAndValidate(assetDetails, diffDetails);
|
||||||
if ( outcome !== true ) { return assetDetails; }
|
if ( outcome !== true ) { return assetDetails; }
|
||||||
assetDetails.status = 'updated';
|
assetDetails.status = 'updated';
|
||||||
assetDetails.diffURL = diffURL;
|
assetDetails.patchURL = patchData.patchURL;
|
||||||
|
assetDetails.patchSize = patchData.patchSize;
|
||||||
return assetDetails;
|
return assetDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,6 +240,8 @@ bc.onmessage = ev => {
|
||||||
case 'update':
|
case 'update':
|
||||||
fetchAndApplyAllPatches(message).then(response => {
|
fetchAndApplyAllPatches(message).then(response => {
|
||||||
bc.postMessage(response);
|
bc.postMessage(response);
|
||||||
|
}).catch(error => {
|
||||||
|
bc.postMessage({ what: 'broken', error });
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue