Distinguish diff patch not-available from not-yet-available

A not-yet-available won't cause a list to become candidate for
full update.

A not-available will cause the list to be candidate for full
update.
This commit is contained in:
Raymond Hill 2023-10-31 10:52:03 -04:00
parent 2d645cdd31
commit abd8577096
No known key found for this signature in database
GPG key ID: 25E1490B761470C2
2 changed files with 51 additions and 6 deletions

View file

@ -1184,6 +1184,8 @@ const getAssetDiffDetails = assetKey => {
if ( cacheEntry.diffName === undefined ) { return; }
out.diffName = cacheEntry.diffName;
out.patchPath = cacheEntry.diffPath;
out.diffExpires = getUpdateAfterTime(assetKey, true);
out.lastModified = cacheEntry.lastModified;
const assetEntry = assetSourceRegistry[assetKey];
if ( assetEntry === undefined ) { return; }
if ( Array.isArray(assetEntry.cdnURLs) === false ) { return; }
@ -1203,7 +1205,8 @@ async function diffUpdater() {
if ( assetDetails.patchPath === undefined ) { continue; }
if ( assetDetails.diffName === undefined ) { continue; }
assetDetails.what = 'update';
if ( (getWriteTime(assetKey) + getUpdateAfterTime(assetKey, true)) > now ) {
if ( (getWriteTime(assetKey) + assetDetails.diffExpires) > now ) {
assetDetails.fetch = false;
toSoftUpdate.push(assetDetails);
} else {
toHardUpdate.push(assetDetails);
@ -1263,6 +1266,13 @@ async function diffUpdater() {
updaterUpdated.push(data.name);
} else if ( data.error ) {
ubolog(`Diff updater: failed to diff-update ${data.name} using ${data.patchPath}, reason: ${data.error}`);
} else {
ubolog(`Diff updater: Skip diff-updating ${data.name} using ${data.patchPath}, reason: ${data.status}`);
if ( data.status === 'nopatch-yet' || data.status === 'nodiff' ) {
assetCacheSetDetails(data.name, {
writeTime: data.lastModified || 0
});
}
}
pendingOps -= 1;
if ( pendingOps === 0 && toSoftUpdate.length !== 0 ) {

View file

@ -56,6 +56,19 @@ const resolveURL = (path, url) => {
}
};
const expectedTimeFromPatch = assetDetails => {
const match = /(\d+)\.(\d+)\.(\d+)\.(\d+)/.exec(assetDetails.patchPath);
if ( match === null ) { return 0; }
const date = new Date();
date.setUTCFullYear(
parseInt(match[1], 10),
parseInt(match[2], 10) - 1,
parseInt(match[3], 10)
);
date.setUTCHours(0, parseInt(match[4], 10), 0, 0);
return date.getTime() + assetDetails.diffExpires;
};
function parsePatch(patch) {
const patchDetails = new Map();
const diffLines = patch.split('\n');
@ -132,6 +145,12 @@ function applyPatch(text, diff) {
return lines.join('\n');
}
function hasPatchDetails(assetDetails) {
const { patchPath } = assetDetails;
const patchFile = basename(patchPath);
return patchFile !== '' && patches.has(patchFile);
}
/******************************************************************************/
// Async
@ -181,9 +200,7 @@ async function fetchPatchDetailsFromCDNs(assetDetails) {
if ( response === undefined ) { continue; }
if ( response.ok !== true ) { continue; }
const patchText = await response.text();
if ( patchText.length === 0 ) { continue; }
const patchDetails = parsePatch(patchText);
if ( patchDetails === undefined ) { continue; }
return {
patchURL,
patchSize: `${(patchText.length / 1000).toFixed(1)} KB`,
@ -200,22 +217,40 @@ async function fetchPatchDetails(assetDetails) {
if ( patches.has(patchFile) ) {
return patches.get(patchFile);
}
if ( assetDetails.fetch === false ) { return null; }
const patchDetailsPromise = fetchPatchDetailsFromCDNs(assetDetails);
patches.set(patchFile, patchDetailsPromise);
return patchDetailsPromise;
}
async function fetchAndApplyAllPatches(assetDetails) {
if ( assetDetails.fetch === false ) {
if ( hasPatchDetails(assetDetails) === false ) {
assetDetails.status = 'nodiff';
return assetDetails;
}
}
// uBO-specific, to avoid pointless fetches which are likely to fail
// because the patch has not yet been created
const patchTime = expectedTimeFromPatch(assetDetails);
if ( patchTime > Date.now() ) {
assetDetails.status = 'nopatch-yet';
return assetDetails;
}
const patchData = await fetchPatchDetails(assetDetails);
if ( patchData === null ) {
assetDetails.error = 'nopatch';
assetDetails.status = (Date.now() - patchTime) < (4 * assetDetails.diffExpires)
? 'nopatch-yet'
: 'nopatch';
return assetDetails;
}
const { patchDetails } = patchData;
if ( patchDetails instanceof Map === false ) {
assetDetails.status = 'nodiff';
return assetDetails;
}
const diffDetails = patchDetails.get(assetDetails.diffName);
if ( diffDetails === undefined ) {
assetDetails.error = 'nodiff';
assetDetails.status = 'nodiff';
return assetDetails;
}
if ( assetDetails.text === undefined ) {