mirror of https://github.com/gorhill/uBlock.git
Ensure reading last data written
Related discussion: https://github.com/uBlockOrigin/uBlock-discussions/discussions/888
This commit is contained in:
parent
800eca7b58
commit
539938969d
|
@ -23,7 +23,6 @@
|
|||
|
||||
import * as s14e from './s14e-serializer.js';
|
||||
|
||||
import lz4Codec from './lz4.js';
|
||||
import { ubolog } from './console.js';
|
||||
import webext from './webext.js';
|
||||
import µb from './background.js';
|
||||
|
@ -32,6 +31,7 @@ import µb from './background.js';
|
|||
|
||||
const STORAGE_NAME = 'uBlock0CacheStorage';
|
||||
const extensionStorage = webext.storage.local;
|
||||
const pendingWrite = new Map();
|
||||
|
||||
const keysFromGetArg = arg => {
|
||||
if ( arg === null || arg === undefined ) { return []; }
|
||||
|
@ -58,8 +58,18 @@ const hasOwnProperty = (o, p) =>
|
|||
|
||||
const cacheStorage = (( ) => {
|
||||
|
||||
const exGet = (api, wanted, outbin) => {
|
||||
return api.get(wanted).then(inbin => {
|
||||
const exGet = async (api, wanted, outbin) => {
|
||||
ubolog('cacheStorage:', api.name || 'storage.local', wanted.join());
|
||||
const missing = [];
|
||||
for ( const key of wanted ) {
|
||||
if ( pendingWrite.has(key) ) {
|
||||
outbin[key] = pendingWrite.get(key);
|
||||
} else {
|
||||
missing.push(key);
|
||||
}
|
||||
}
|
||||
if ( missing.length === 0 ) { return; }
|
||||
return api.get(missing).then(inbin => {
|
||||
inbin = inbin || {};
|
||||
const found = Object.keys(inbin);
|
||||
Object.assign(outbin, inbin);
|
||||
|
@ -139,16 +149,26 @@ const cacheStorage = (( ) => {
|
|||
async set(rawbin) {
|
||||
const keys = Object.keys(rawbin);
|
||||
if ( keys.length === 0 ) { return; }
|
||||
const serializedbin = {};
|
||||
const promises = [];
|
||||
for ( const key of keys ) {
|
||||
promises.push(compress(serializedbin, key, rawbin[key]));
|
||||
pendingWrite.set(key, rawbin[key]);
|
||||
}
|
||||
await Promise.all(promises);
|
||||
cacheAPIs[fastCache].set(rawbin, serializedbin);
|
||||
return extensionStorage.set(serializedbin).catch(reason => {
|
||||
try {
|
||||
const serializedbin = {};
|
||||
const promises = [];
|
||||
for ( const key of keys ) {
|
||||
promises.push(compress(serializedbin, key, rawbin[key]));
|
||||
}
|
||||
await Promise.all(promises);
|
||||
await Promise.all([
|
||||
cacheAPIs[fastCache].set(rawbin, serializedbin),
|
||||
extensionStorage.set(serializedbin),
|
||||
]);
|
||||
} catch(reason) {
|
||||
ubolog(reason);
|
||||
});
|
||||
}
|
||||
for ( const key of keys ) {
|
||||
pendingWrite.delete(key);
|
||||
}
|
||||
},
|
||||
|
||||
remove(...args) {
|
||||
|
@ -295,6 +315,7 @@ const cacheAPI = (( ) => {
|
|||
};
|
||||
|
||||
return {
|
||||
name: 'cacheAPI',
|
||||
async get(arg) {
|
||||
const keys = keysFromGetArg(arg);
|
||||
if ( keys === undefined ) { return; }
|
||||
|
@ -393,6 +414,7 @@ const memoryStorage = (( ) => {
|
|||
};
|
||||
|
||||
return {
|
||||
name: 'memoryStorage',
|
||||
get(...args) {
|
||||
return sessionStorage.get(...args).then(bin => {
|
||||
return bin;
|
||||
|
@ -491,25 +513,6 @@ const idbStorage = (( ) => {
|
|||
return /^cache\/(compiled|selfie)\//.test(key);
|
||||
};
|
||||
|
||||
const fromBlob = data => {
|
||||
if ( data instanceof Blob === false ) {
|
||||
return Promise.resolve(data);
|
||||
}
|
||||
return new Promise(resolve => {
|
||||
const blobReader = new FileReader();
|
||||
blobReader.onloadend = ev => {
|
||||
resolve(new Uint8Array(ev.target.result));
|
||||
};
|
||||
blobReader.readAsArrayBuffer(data);
|
||||
});
|
||||
};
|
||||
|
||||
const decompress = (key, value) => {
|
||||
return lz4Codec.decode(value, fromBlob).then(value => {
|
||||
return { key, value };
|
||||
});
|
||||
};
|
||||
|
||||
const getAllEntries = async function() {
|
||||
const db = await getDb();
|
||||
if ( db === null ) { return []; }
|
||||
|
@ -527,9 +530,7 @@ const idbStorage = (( ) => {
|
|||
const cursor = ev.target && ev.target.result;
|
||||
if ( !cursor ) { return; }
|
||||
const { key, value } = cursor.value;
|
||||
if ( value instanceof Blob ) {
|
||||
entries.push(decompress(key, value));
|
||||
} else {
|
||||
if ( value instanceof Blob === false ) {
|
||||
entries.push({ key, value });
|
||||
}
|
||||
cursor.continue();
|
||||
|
@ -576,11 +577,8 @@ const idbStorage = (( ) => {
|
|||
if ( typeof result !== 'object' ) { return; }
|
||||
if ( result === null ) { return; }
|
||||
const { key, value } = result;
|
||||
if ( value instanceof Blob ) {
|
||||
entries.push(decompress(key, value));
|
||||
} else {
|
||||
entries.push({ key, value });
|
||||
}
|
||||
if ( value instanceof Blob ) { return; }
|
||||
entries.push({ key, value });
|
||||
};
|
||||
const transaction = db.transaction(STORAGE_NAME, 'readonly');
|
||||
transaction.oncomplete =
|
||||
|
@ -656,6 +654,7 @@ const idbStorage = (( ) => {
|
|||
};
|
||||
|
||||
return {
|
||||
name: 'idbStorage',
|
||||
async get(argbin) {
|
||||
const keys = keysFromGetArg(argbin);
|
||||
if ( keys === undefined ) { return; }
|
||||
|
|
|
@ -45,7 +45,6 @@ import { filteringBehaviorChanged } from './broadcast.js';
|
|||
import cacheStorage from './cachestorage.js';
|
||||
import { ubolog } from './console.js';
|
||||
import contextMenu from './contextmenu.js';
|
||||
import lz4Codec from './lz4.js';
|
||||
import { redirectEngine } from './redirect-engine.js';
|
||||
import staticFilteringReverseLookup from './reverselookup.js';
|
||||
import staticExtFilteringEngine from './static-ext-filtering.js';
|
||||
|
@ -490,13 +489,6 @@ await initializeTabs();
|
|||
// Start network observers.
|
||||
webRequest.start();
|
||||
|
||||
// Ensure that the resources allocated for decompression purpose (likely
|
||||
// large buffers) are garbage-collectable immediately after launch.
|
||||
// Otherwise I have observed that it may take quite a while before the
|
||||
// garbage collection of these resources kicks in. Relinquishing as soon
|
||||
// as possible ensure minimal memory usage baseline.
|
||||
lz4Codec.relinquish();
|
||||
|
||||
// Force an update of the context menu according to the currently
|
||||
// active tab.
|
||||
contextMenu.update();
|
||||
|
|
|
@ -38,7 +38,6 @@ import cosmeticFilteringEngine from './cosmetic-filtering.js';
|
|||
import { hostnameFromURI } from './uri-utils.js';
|
||||
import io from './assets.js';
|
||||
import logger from './logger.js';
|
||||
import lz4Codec from './lz4.js';
|
||||
import publicSuffixList from '../lib/publicsuffixlist/publicsuffixlist.js';
|
||||
import punycode from '../lib/punycode.js';
|
||||
import { redirectEngine } from './redirect-engine.js';
|
||||
|
@ -928,7 +927,6 @@ onBroadcast(msg => {
|
|||
});
|
||||
|
||||
µb.selfieManager.destroy();
|
||||
lz4Codec.relinquish();
|
||||
µb.compiledFormatChanged = false;
|
||||
|
||||
loadingPromise = undefined;
|
||||
|
@ -1324,7 +1322,6 @@ onBroadcast(msg => {
|
|||
staticNetFilteringEngine.toSelfie()
|
||||
),
|
||||
]);
|
||||
lz4Codec.relinquish();
|
||||
µb.selfieIsInvalid = false;
|
||||
ubolog('Filtering engine selfie created');
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue