Skip to content

Commit 592d12d

Browse files
authored
[file_packager] Convert preload caching functions to async. NFC (#24885)
The 3 functions related to IDB caching of preload data are now marked as `async`. This means that they return promises instead of using callbacks. Followup to #24882 and #24883
1 parent 7990b15 commit 592d12d

File tree

1 file changed

+103
-97
lines changed

1 file changed

+103
-97
lines changed

tools/file_packager.py

Lines changed: 103 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,7 @@ def generate_js(data_target, data_files, metadata):
805805
var DB_VERSION = 1;
806806
var METADATA_STORE_NAME = 'METADATA';
807807
var PACKAGE_STORE_NAME = 'PACKAGES';
808+
808809
async function openDatabase() {
809810
if (typeof indexedDB == 'undefined') {
810811
throw 'using IndexedDB to cache data can only be done on a web page or in a web worker';
@@ -838,67 +839,68 @@ def generate_js(data_target, data_files, metadata):
838839
// We set the chunk size to 64MB to stay well-below the limit
839840
var CHUNK_SIZE = 64 * 1024 * 1024;
840841
841-
function cacheRemotePackage(
842-
db,
843-
packageName,
844-
packageData,
845-
packageMeta,
846-
callback,
847-
errback
848-
) {
842+
async function cacheRemotePackage(db, packageName, packageData, packageMeta) {
849843
var transactionPackages = db.transaction([PACKAGE_STORE_NAME], IDB_RW);
850844
var packages = transactionPackages.objectStore(PACKAGE_STORE_NAME);
851845
var chunkSliceStart = 0;
852846
var nextChunkSliceStart = 0;
853847
var chunkCount = Math.ceil(packageData.byteLength / CHUNK_SIZE);
854848
var finishedChunks = 0;
855-
for (var chunkId = 0; chunkId < chunkCount; chunkId++) {
856-
nextChunkSliceStart += CHUNK_SIZE;
857-
var putPackageRequest = packages.put(
858-
packageData.slice(chunkSliceStart, nextChunkSliceStart),
859-
`package/${packageName}/${chunkId}`
860-
);
861-
chunkSliceStart = nextChunkSliceStart;
862-
putPackageRequest.onsuccess = (event) => {
863-
finishedChunks++;
864-
if (finishedChunks == chunkCount) {
865-
var transaction_metadata = db.transaction(
866-
[METADATA_STORE_NAME],
867-
IDB_RW
868-
);
869-
var metadata = transaction_metadata.objectStore(METADATA_STORE_NAME);
870-
var putMetadataRequest = metadata.put(
871-
{
872-
'uuid': packageMeta.uuid,
873-
'chunkCount': chunkCount
874-
},
875-
`metadata/${packageName}`
876-
);
877-
putMetadataRequest.onsuccess = (event) => callback(packageData);
878-
putMetadataRequest.onerror = (error) => errback(error);
879-
}
880-
};
881-
putPackageRequest.onerror = (error) => errback(error);
882-
}
849+
850+
return new Promise((resolve, reject) => {
851+
for (var chunkId = 0; chunkId < chunkCount; chunkId++) {
852+
nextChunkSliceStart += CHUNK_SIZE;
853+
var putPackageRequest = packages.put(
854+
packageData.slice(chunkSliceStart, nextChunkSliceStart),
855+
`package/${packageName}/${chunkId}`
856+
);
857+
chunkSliceStart = nextChunkSliceStart;
858+
putPackageRequest.onsuccess = (event) => {
859+
finishedChunks++;
860+
if (finishedChunks == chunkCount) {
861+
var transaction_metadata = db.transaction(
862+
[METADATA_STORE_NAME],
863+
IDB_RW
864+
);
865+
var metadata = transaction_metadata.objectStore(METADATA_STORE_NAME);
866+
var putMetadataRequest = metadata.put(
867+
{
868+
'uuid': packageMeta.uuid,
869+
'chunkCount': chunkCount
870+
},
871+
`metadata/${packageName}`
872+
);
873+
putMetadataRequest.onsuccess = (event) => resolve(packageData);
874+
putMetadataRequest.onerror = reject;
875+
}
876+
};
877+
putPackageRequest.onerror = reject;
878+
}
879+
});
883880
}
884881
885-
/* Check if there's a cached package, and if so whether it's the latest available */
886-
function checkCachedPackage(db, packageName, callback, errback) {
882+
/*
883+
* Check if there's a cached package, and if so whether it's the latest available.
884+
* Resolves to the cached metadata, or `null` if it is missing or out-of-date.
885+
*/
886+
async function checkCachedPackage(db, packageName) {
887887
var transaction = db.transaction([METADATA_STORE_NAME], IDB_RO);
888888
var metadata = transaction.objectStore(METADATA_STORE_NAME);
889889
var getRequest = metadata.get(`metadata/${packageName}`);
890-
getRequest.onsuccess = (event) => {
891-
var result = event.target.result;
892-
if (!result) {
893-
return callback(false, null);
894-
} else {
895-
return callback(PACKAGE_UUID === result['uuid'], result);
890+
return new Promise((resolve, reject) => {
891+
getRequest.onsuccess = (event) => {
892+
var result = event.target.result;
893+
if (result && PACKAGE_UUID === result['uuid']) {
894+
resolve(result);
895+
} else {
896+
resolve(null);
897+
}
896898
}
897-
};
898-
getRequest.onerror = (error) => errback(error);
899+
getRequest.onerror = reject;
900+
});
899901
}
900902
901-
function fetchCachedPackage(db, packageName, metadata, callback, errback) {
903+
async function fetchCachedPackage(db, packageName, metadata) {
902904
var transaction = db.transaction([PACKAGE_STORE_NAME], IDB_RO);
903905
var packages = transaction.objectStore(PACKAGE_STORE_NAME);
904906
@@ -907,41 +909,43 @@ def generate_js(data_target, data_files, metadata):
907909
var chunkCount = metadata['chunkCount'];
908910
var chunks = new Array(chunkCount);
909911
910-
for (var chunkId = 0; chunkId < chunkCount; chunkId++) {
911-
var getRequest = packages.get(`package/${packageName}/${chunkId}`);
912-
getRequest.onsuccess = (event) => {
913-
if (!event.target.result) {
914-
errback(new Error(`CachedPackageNotFound for: ${packageName}`));
915-
return;
916-
}
917-
// If there's only 1 chunk, there's nothing to concatenate it with so we can just return it now
918-
if (chunkCount == 1) {
919-
callback(event.target.result);
920-
} else {
921-
chunksDone++;
922-
totalSize += event.target.result.byteLength;
923-
chunks.push(event.target.result);
924-
if (chunksDone == chunkCount) {
925-
if (chunksDone == 1) {
926-
callback(event.target.result);
927-
} else {
928-
var tempTyped = new Uint8Array(totalSize);
929-
var byteOffset = 0;
930-
for (var chunkId in chunks) {
931-
var buffer = chunks[chunkId];
932-
tempTyped.set(new Uint8Array(buffer), byteOffset);
933-
byteOffset += buffer.byteLength;
934-
buffer = undefined;
912+
return new Promise((resolve, reject) => {
913+
for (var chunkId = 0; chunkId < chunkCount; chunkId++) {
914+
var getRequest = packages.get(`package/${packageName}/${chunkId}`);
915+
getRequest.onsuccess = (event) => {
916+
if (!event.target.result) {
917+
reject(`CachedPackageNotFound for: ${packageName}`);
918+
return;
919+
}
920+
// If there's only 1 chunk, there's nothing to concatenate it with so we can just return it now
921+
if (chunkCount == 1) {
922+
resolve(event.target.result);
923+
} else {
924+
chunksDone++;
925+
totalSize += event.target.result.byteLength;
926+
chunks.push(event.target.result);
927+
if (chunksDone == chunkCount) {
928+
if (chunksDone == 1) {
929+
resolve(event.target.result);
930+
} else {
931+
var tempTyped = new Uint8Array(totalSize);
932+
var byteOffset = 0;
933+
for (var chunkId in chunks) {
934+
var buffer = chunks[chunkId];
935+
tempTyped.set(new Uint8Array(buffer), byteOffset);
936+
byteOffset += buffer.byteLength;
937+
buffer = undefined;
938+
}
939+
chunks = undefined;
940+
resolve(tempTyped.buffer);
941+
tempTyped = undefined;
935942
}
936-
chunks = undefined;
937-
callback(tempTyped.buffer);
938-
tempTyped = undefined;
939943
}
940944
}
941-
}
942-
};
943-
getRequest.onerror = (error) => errback(error);
944-
}
945+
};
946+
getRequest.onerror = reject;
947+
}
948+
});
945949
}\n'''
946950

947951
# add Node.js support code, if necessary
@@ -1044,24 +1048,26 @@ def generate_js(data_target, data_files, metadata):
10441048
};
10451049
10461050
openDatabase()
1047-
.then((db) => checkCachedPackage(db, PACKAGE_PATH + PACKAGE_NAME,
1048-
(useCached, metadata) => {
1049-
Module['preloadResults'][PACKAGE_NAME] = {fromCache: useCached};
1050-
if (useCached) {
1051-
fetchCachedPackage(db, PACKAGE_PATH + PACKAGE_NAME, metadata, processPackageData, preloadFallback);
1052-
} else {
1053-
fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE,
1054-
(packageData) => {
1055-
cacheRemotePackage(db, PACKAGE_PATH + PACKAGE_NAME, packageData, {uuid:PACKAGE_UUID}, processPackageData,
1056-
(error) => {
1057-
console.error(error);
1058-
processPackageData(packageData);
1059-
});
1060-
}
1061-
, preloadFallback);
1062-
}
1063-
}, preloadFallback))
1064-
.catch(preloadFallback);
1051+
.then((db) => {
1052+
checkCachedPackage(db, PACKAGE_PATH + PACKAGE_NAME)
1053+
.then((cachedData) => {
1054+
Module['preloadResults'][PACKAGE_NAME] = {fromCache: !!cachedData};
1055+
if (cachedData) {
1056+
fetchCachedPackage(db, PACKAGE_PATH + PACKAGE_NAME, cachedData).then(processPackageData);
1057+
} else {
1058+
fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE,
1059+
(packageData) => {
1060+
cacheRemotePackage(db, PACKAGE_PATH + PACKAGE_NAME, packageData, {uuid:PACKAGE_UUID})
1061+
.then(processPackageData)
1062+
.catch((error) => {
1063+
console.error(error);
1064+
processPackageData(packageData);
1065+
});
1066+
}
1067+
, preloadFallback);
1068+
}
1069+
})
1070+
}).catch(preloadFallback);
10651071
10661072
Module['setStatus']?.('Downloading...');\n'''
10671073
else:

0 commit comments

Comments
 (0)