Skip to content

Commit 69fce3a

Browse files
committed
Fine-tune details about when differential update should kick in
Manual update of one or more lists will cause the most recent version of these lists to be fetched from the "origin" server, and since the lists from "origin" servers cannot be updated through differential update, the lists will be subsequently updated according to their `Expires` directive. When the lists are auto-updated, the "CDN" servers will be used, and as a result the lists will start to be updated trhough differential updates every 6-hour (currently). Thus it is recommended and optimal to let the lists auto-update, since you will benefit from a much shorter delay to get up-to-date lists (i.e. every 6-hour instead of every 6-day). You can force the auto-updater to fetch all the lists by clicking "Purge all caches", then restart uBO without clicking "Update". This will cause uBO to perform an emergency auto-update at restart time, after which you will have all the lists which are candidates for differential update. The "Update now" button in the "Support" pane will also cause lists to be fetched from their "origin" server.
1 parent 2acf8a6 commit 69fce3a

File tree

3 files changed

+66
-66
lines changed

3 files changed

+66
-66
lines changed

src/js/assets.js

Lines changed: 59 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@
2626
import cacheStorage from './cachestorage.js';
2727
import logger from './logger.js';
2828
import µb from './background.js';
29+
import { ubolog } from './console.js';
2930
import { i18n$ } from './i18n.js';
3031
import * as sfp from './static-filtering-parser.js';
31-
import { ubolog } from './console.js';
32+
import { orphanizeString, } from './text-utils.js';
3233

3334
/******************************************************************************/
3435

@@ -47,6 +48,8 @@ let remoteServerFriendly = false;
4748

4849
/******************************************************************************/
4950

51+
const stringIsNotEmpty = s => typeof s === 'string' && s !== '';
52+
5053
const parseExpires = s => {
5154
const matches = s.match(/(\d+)\s*([dh])?/i);
5255
if ( matches === null ) { return 0; }
@@ -71,7 +74,7 @@ const extractMetadataFromList = (content, fields) => {
7174
field = field.toLowerCase().replace(
7275
/-[a-z]/g, s => s.charAt(1).toUpperCase()
7376
);
74-
out[field] = value;
77+
out[field] = value && orphanizeString(value);
7578
}
7679
// Pre-process known fields
7780
if ( out.lastModified ) {
@@ -169,7 +172,44 @@ const isDiffUpdatableAsset = content => {
169172
/^[^%].*[^%]$/.test(data.diffPath);
170173
};
171174

172-
const stringIsNotEmpty = s => typeof s === 'string' && s !== '';
175+
/******************************************************************************/
176+
177+
// favorLocal: avoid making network requests whenever possible
178+
// favorOrigin: avoid using CDN URLs whenever possible
179+
180+
const getContentURLs = (assetKey, options = {}) => {
181+
const contentURLs = [];
182+
const entry = assetSourceRegistry[assetKey];
183+
if ( entry instanceof Object === false ) { return contentURLs; }
184+
if ( typeof entry.contentURL === 'string' ) {
185+
contentURLs.push(entry.contentURL);
186+
} else if ( Array.isArray(entry.contentURL) ) {
187+
contentURLs.push(...entry.contentURL);
188+
} else if ( reIsExternalPath.test(assetKey) ) {
189+
contentURLs.push(assetKey);
190+
}
191+
if ( options.favorLocal ) {
192+
contentURLs.sort((a, b) => {
193+
if ( reIsExternalPath.test(a) ) { return 1; }
194+
if ( reIsExternalPath.test(b) ) { return -1; }
195+
return 0;
196+
});
197+
}
198+
if ( Array.isArray(entry.cdnURLs) ) {
199+
const cdnURLs = entry.cdnURLs.slice();
200+
for ( let i = 0, n = cdnURLs.length; i < n; i++ ) {
201+
const j = Math.floor(Math.random() * n);
202+
if ( j === i ) { continue; }
203+
[ cdnURLs[j], cdnURLs[i] ] = [ cdnURLs[i], cdnURLs[j] ];
204+
}
205+
if ( options.favorLocal || options.favorOrigin ) {
206+
contentURLs.push(...cdnURLs);
207+
} else {
208+
contentURLs.unshift(...cdnURLs);
209+
}
210+
}
211+
return contentURLs;
212+
};
173213

174214
/******************************************************************************/
175215

@@ -917,28 +957,17 @@ assets.get = async function(assetKey, options = {}) {
917957
}
918958

919959
const assetRegistry = await getAssetSourceRegistry();
960+
920961
assetDetails = assetRegistry[assetKey] || {};
921-
const contentURLs = [];
922-
if ( typeof assetDetails.contentURL === 'string' ) {
923-
contentURLs.push(assetDetails.contentURL);
924-
} else if ( Array.isArray(assetDetails.contentURL) ) {
925-
contentURLs.push(...assetDetails.contentURL);
926-
} else if ( reIsExternalPath.test(assetKey) ) {
962+
963+
const contentURLs = getContentURLs(assetKey, options);
964+
if ( contentURLs.length === 0 && reIsExternalPath.test(assetKey) ) {
927965
assetDetails.content = 'filters';
928966
contentURLs.push(assetKey);
929967
}
930968

931-
// https://github.com/uBlockOrigin/uBlock-issues/issues/1566#issuecomment-826473517
932-
// Use CDN URLs as fall back URLs.
933-
if ( Array.isArray(assetDetails.cdnURLs) ) {
934-
contentURLs.push(...assetDetails.cdnURLs);
935-
}
936-
937969
let error = 'ENOTFOUND';
938970
for ( const contentURL of contentURLs ) {
939-
if ( reIsExternalPath.test(contentURL) && assetDetails.hasLocalURL ) {
940-
continue;
941-
}
942971
const details = assetDetails.content === 'filters'
943972
? await assets.fetchFilterList(contentURL)
944973
: await assets.fetchText(contentURL);
@@ -966,7 +995,7 @@ assets.get = async function(assetKey, options = {}) {
966995

967996
/******************************************************************************/
968997

969-
async function getRemote(assetKey) {
998+
async function getRemote(assetKey, options = {}) {
970999
const [
9711000
assetDetails = {},
9721001
cacheDetails = {},
@@ -978,56 +1007,19 @@ async function getRemote(assetKey) {
9781007
let error;
9791008
let stale = false;
9801009

981-
const reportBack = function(content, err) {
982-
const details = { assetKey, content };
983-
if ( err ) {
1010+
const reportBack = function(content, url = '', err = '') {
1011+
const details = { assetKey, content, url };
1012+
if ( err !== '') {
9841013
details.error = assetDetails.lastError = err;
9851014
} else {
9861015
assetDetails.lastError = undefined;
9871016
}
9881017
return details;
9891018
};
9901019

991-
const contentURLs = [];
992-
if ( typeof assetDetails.contentURL === 'string' ) {
993-
contentURLs.push(assetDetails.contentURL);
994-
} else if ( Array.isArray(assetDetails.contentURL) ) {
995-
contentURLs.push(...assetDetails.contentURL);
996-
}
997-
998-
// If asked to be gentle on remote servers, favour using dedicated CDN
999-
// servers. If more than one CDN server is present, randomly shuffle the
1000-
// set of servers so as to spread the bandwidth burden.
1001-
//
1002-
// https://github.com/uBlockOrigin/uBlock-issues/issues/1566#issuecomment-826473517
1003-
// In case of manual update, use CDNs URLs as fall back URLs.
1004-
if ( Array.isArray(assetDetails.cdnURLs) ) {
1005-
const cdnURLs = assetDetails.cdnURLs.slice();
1006-
for ( let i = 0, n = cdnURLs.length; i < n; i++ ) {
1007-
const j = Math.floor(Math.random() * n);
1008-
if ( j === i ) { continue; }
1009-
[ cdnURLs[j], cdnURLs[i] ] = [ cdnURLs[i], cdnURLs[j] ];
1010-
}
1011-
if ( remoteServerFriendly ) {
1012-
contentURLs.unshift(...cdnURLs);
1013-
} else {
1014-
contentURLs.push(...cdnURLs);
1015-
}
1016-
}
1017-
1018-
for ( let contentURL of contentURLs ) {
1020+
for ( const contentURL of getContentURLs(assetKey, options) ) {
10191021
if ( reIsExternalPath.test(contentURL) === false ) { continue; }
10201022

1021-
// This will force uBO to fetch the proper version according to whether
1022-
// the dev build is being used. This can be removed when execution of
1023-
// this code path is widespread for dev build revisions of uBO.
1024-
if ( assetKey === 'assets.json' ) {
1025-
contentURL = contentURL.replace(
1026-
/\/assets\/assets\.json$/,
1027-
µb.assetsJsonPath
1028-
);
1029-
}
1030-
10311023
const result = assetDetails.content === 'filters'
10321024
? await assets.fetchFilterList(contentURL)
10331025
: await assets.fetchText(contentURL);
@@ -1066,12 +1058,12 @@ async function getRemote(assetKey) {
10661058
}
10671059

10681060
registerAssetSource(assetKey, { birthtime: undefined, error: undefined });
1069-
return reportBack(result.content);
1061+
return reportBack(result.content, contentURL);
10701062
}
10711063

10721064
if ( error !== undefined ) {
10731065
registerAssetSource(assetKey, { error: { time: Date.now(), error } });
1074-
return reportBack('', 'ENOTFOUND');
1066+
return reportBack('', '', 'ENOTFOUND');
10751067
}
10761068

10771069
if ( stale ) {
@@ -1194,6 +1186,8 @@ const getAssetDiffDetails = assetKey => {
11941186
};
11951187

11961188
async function diffUpdater() {
1189+
if ( updaterAuto === false ) { return; }
1190+
if ( µb.hiddenSettings.differentialUpdate === false ) { return; }
11971191
const toUpdate = await getUpdateCandidates();
11981192
const now = Date.now();
11991193
const toHardUpdate = [];
@@ -1298,6 +1292,7 @@ async function diffUpdater() {
12981292

12991293
function updateFirst() {
13001294
ubolog('Updater: cycle start');
1295+
ubolog('Updater: Fetch from ', updaterAuto ? 'CDNs' : 'origin');
13011296
updaterStatus = 'updating';
13021297
updaterFetched.clear();
13031298
updaterUpdated.length = 0;
@@ -1367,7 +1362,7 @@ async function updateNext() {
13671362

13681363
let result;
13691364
if ( assetKey !== 'assets.json' || µb.hiddenSettings.debugAssetsJson !== true ) {
1370-
result = await getRemote(assetKey);
1365+
result = await getRemote(assetKey, { favorOrigin: updaterAuto === false });
13711366
} else {
13721367
result = await assets.fetchText(µb.assetsJsonPath);
13731368
result.assetKey = 'assets.json';
@@ -1396,6 +1391,7 @@ function updateDone() {
13961391
updaterFetched.clear();
13971392
updaterUpdated.length = 0;
13981393
updaterStatus = undefined;
1394+
updaterAuto = false;
13991395
updaterAssetDelay = updaterAssetDelayDefault;
14001396
ubolog('Updater: cycle end');
14011397
if ( assetKeys.length ) {

src/js/background.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ const hiddenSettingsDefault = {
4949
allowGenericProceduralFilters: false,
5050
assetFetchTimeout: 30,
5151
autoCommentFilterTemplate: '{{date}} {{origin}}',
52-
autoUpdateAssetFetchPeriod: 60,
52+
autoUpdateAssetFetchPeriod: 15,
5353
autoUpdateDelayAfterLaunch: 105,
54-
autoUpdatePeriod: 2,
54+
autoUpdatePeriod: 1,
5555
benchmarkDatasetURL: 'unset',
5656
blockingProfiles: '11111/#F00 11010/#C0F 11001/#00F 00001',
5757
cacheStorageAPI: 'unset',
@@ -69,6 +69,7 @@ const hiddenSettingsDefault = {
6969
debugAssetsJson: false,
7070
debugScriptlets: false,
7171
debugScriptletInjector: false,
72+
differentialUpdate: true,
7273
disableWebAssembly: false,
7374
extensionUpdateForceReload: false,
7475
filterAuthorMode: false,

src/js/storage.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,10 @@ import {
981981
return { assetKey, content: '' };
982982
}
983983

984-
const rawDetails = await io.get(assetKey, { silent: true });
984+
const rawDetails = await io.get(assetKey, {
985+
favorLocal: this.readyToFilter !== true,
986+
silent: true,
987+
});
985988
// Compiling an empty string results in an empty string.
986989
if ( rawDetails.content === '' ) {
987990
rawDetails.assetKey = assetKey;

0 commit comments

Comments
 (0)