Skip to content

Commit 6d48d48

Browse files
committed
[file_packages] Convert fetchRemotePackage to async. NFC
Part 4 in the sequence following #24882, #24883 and #24885.
1 parent af78792 commit 6d48d48

File tree

2 files changed

+86
-95
lines changed

2 files changed

+86
-95
lines changed

test/test_other.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3984,10 +3984,7 @@ def test_file_packager_modularize(self):
39843984

39853985
create_file('post.js', 'MyModule(Module).then(() => console.log("done"));')
39863986

3987-
self.run_process([EMCC, 'main.c', '--extern-pre-js=embed.js', '--extern-post-js=post.js', '-sMODULARIZE', '-sEXPORT_NAME=MyModule', '-sFORCE_FILESYSTEM'])
3988-
3989-
result = self.run_js('a.out.js')
3990-
self.assertContained('|hello world|', result)
3987+
self.do_runf('main.c', '|hello world|', cflags=['--extern-pre-js=embed.js', '--extern-post-js=post.js', '-sMODULARIZE', '-sEXPORT_NAME=MyModule', '-sFORCE_FILESYSTEM'])
39913988

39923989
def test_preprocess(self):
39933990
# Pass -Werror to prevent regressions such as https://github.com/emscripten-core/emscripten/pull/9661

tools/file_packager.py

Lines changed: 85 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ def generate_js(data_target, data_files, metadata):
635635

636636
if options.support_node:
637637
ret += " var isNode = typeof process === 'object' && typeof process.versions === 'object' && typeof process.versions.node === 'string';\n"
638-
ret += ' function loadPackage(metadata) {\n'
638+
ret += ' async function loadPackage(metadata) {\n'
639639

640640
code = '''
641641
function assert(check, msg) {
@@ -953,76 +953,62 @@ def generate_js(data_target, data_files, metadata):
953953
if options.support_node:
954954
node_support_code = '''
955955
if (isNode) {
956-
require('fs').readFile(packageName, (err, contents) => {
957-
if (err) {
958-
errback(err);
959-
} else {
960-
callback(contents.buffer);
961-
}
962-
});
963-
return;
956+
var fsPromises = require('fs/promises');
957+
var contents = await fsPromises.readFile(packageName);
958+
return contents.buffer;
964959
}'''.strip()
965960

966961
ret += '''
967-
function fetchRemotePackage(packageName, packageSize, callback, errback) {
962+
async function fetchRemotePackage(packageName, packageSize) {
968963
%(node_support_code)s
969964
Module['dataFileDownloads'] ??= {};
970-
fetch(packageName)
971-
.catch((cause) => Promise.reject(new Error(`Network Error: ${packageName}`, {cause}))) // If fetch fails, rewrite the error to include the failing URL & the cause.
972-
.then((response) => {
973-
if (!response.ok) {
974-
return Promise.reject(new Error(`${response.status}: ${response.url}`));
975-
}
965+
var response = await fetch(packageName);
966+
if (!response.ok) {
967+
throw `${response.status}: ${response.url}`;
968+
}
976969
977-
if (!response.body && response.arrayBuffer) { // If we're using the polyfill, readers won't be available...
978-
return response.arrayBuffer().then(callback);
979-
}
970+
if (!response.body && response.arrayBuffer) { // If we're using the polyfill, readers won't be available...
971+
return response.arrayBuffer();
972+
}
980973
981-
const reader = response.body.getReader();
982-
const iterate = () => reader.read().then(handleChunk).catch((cause) => {
983-
return Promise.reject(new Error(`Unexpected error while handling : ${response.url} ${cause}`, {cause}));
984-
});
974+
const chunks = [];
975+
const headers = response.headers;
976+
const total = Number(headers.get('Content-Length') ?? packageSize);
977+
let loaded = 0;
985978
986-
const chunks = [];
987-
const headers = response.headers;
988-
const total = Number(headers.get('Content-Length') ?? packageSize);
989-
let loaded = 0;
979+
Module['setStatus']?.('Downloading data...');
980+
const reader = response.body.getReader();
990981
991-
const handleChunk = ({done, value}) => {
992-
if (!done) {
993-
chunks.push(value);
994-
loaded += value.length;
995-
Module['dataFileDownloads'][packageName] = {loaded, total};
982+
while (1) {
983+
var {done, value} = await reader.read();
984+
if (done) break;
985+
chunks.push(value);
986+
loaded += value.length;
987+
Module['dataFileDownloads'][packageName] = {loaded, total};
996988
997-
let totalLoaded = 0;
998-
let totalSize = 0;
989+
let totalLoaded = 0;
990+
let totalSize = 0;
999991
1000-
for (const download of Object.values(Module['dataFileDownloads'])) {
1001-
totalLoaded += download.loaded;
1002-
totalSize += download.total;
1003-
}
992+
for (const download of Object.values(Module['dataFileDownloads'])) {
993+
totalLoaded += download.loaded;
994+
totalSize += download.total;
995+
}
1004996
1005-
Module['setStatus']?.(`Downloading data... (${totalLoaded}/${totalSize})`);
1006-
return iterate();
1007-
} else {
1008-
const packageData = new Uint8Array(chunks.map((c) => c.length).reduce((a, b) => a + b, 0));
1009-
let offset = 0;
1010-
for (const chunk of chunks) {
1011-
packageData.set(chunk, offset);
1012-
offset += chunk.length;
1013-
}
1014-
callback(packageData.buffer);
1015-
}
1016-
};
997+
Module['setStatus']?.(`Downloading data... (${totalLoaded}/${totalSize})`);
998+
}
1017999
1018-
Module['setStatus']?.('Downloading data...');
1019-
return iterate();
1020-
});
1021-
};
1000+
const packageData = new Uint8Array(chunks.map((c) => c.length).reduce((a, b) => a + b, 0));
1001+
let offset = 0;
1002+
for (const chunk of chunks) {
1003+
packageData.set(chunk, offset);
1004+
offset += chunk.length;
1005+
}
1006+
return packageData.buffer;
1007+
}
10221008
10231009
function handleError(error) {
10241010
console.error('package error:', error);
1025-
};\n''' % {'node_support_code': node_support_code}
1011+
}\n''' % {'node_support_code': node_support_code}
10261012

10271013
code += '''
10281014
function processPackageData(arrayBuffer) {
@@ -1031,7 +1017,7 @@ def generate_js(data_target, data_files, metadata):
10311017
var byteArray = new Uint8Array(arrayBuffer);
10321018
var curr;
10331019
%s
1034-
};
1020+
}
10351021
Module['addRunDependency']('datafile_%s');\n''' % (use_data, js_manipulation.escape_for_js_string(data_target))
10361022
# use basename because from the browser's point of view,
10371023
# we need to find the datafile in the same dir as the html file
@@ -1041,33 +1027,35 @@ def generate_js(data_target, data_files, metadata):
10411027

10421028
if options.use_preload_cache:
10431029
code += '''
1044-
function preloadFallback(error) {
1030+
async function preloadFallback(error) {
10451031
console.error(error);
10461032
console.error('falling back to default preload behavior');
1047-
fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE, processPackageData, handleError);
1048-
};
1049-
1050-
openDatabase()
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);
1033+
try {
1034+
processPackageData(await fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE));
1035+
} catch (e) {
1036+
handleError(e);
1037+
}
1038+
}
1039+
1040+
try {
1041+
var db = await openDatabase();
1042+
var pkgMetadata = await checkCachedPackage(db, PACKAGE_PATH + PACKAGE_NAME);
1043+
var useCached = !!pkgMetadata;
1044+
Module['preloadResults'][PACKAGE_NAME] = {fromCache: useCached};
1045+
if (useCached) {
1046+
processPackageData(await fetchCachedPackage(db, PACKAGE_PATH + PACKAGE_NAME, pkgMetadata));
1047+
} else {
1048+
var packageData = await fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE);
1049+
try {
1050+
processPackageData(await cacheRemotePackage(db, PACKAGE_PATH + PACKAGE_NAME, packageData, {uuid:PACKAGE_UUID}))
1051+
} catch (error) {
1052+
console.error(error);
1053+
processPackageData(packageData);
1054+
}
1055+
}
1056+
} catch(e) {
1057+
await preloadFallback(e);
1058+
}
10711059
10721060
Module['setStatus']?.('Downloading...');\n'''
10731061
else:
@@ -1079,14 +1067,20 @@ def generate_js(data_target, data_files, metadata):
10791067
var fetchedCallback = null;
10801068
var fetched = Module['getPreloadedPackage'] ? Module['getPreloadedPackage'](REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE) : null;
10811069
1082-
if (!fetched) fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE, (data) => {
1083-
if (fetchedCallback) {
1084-
fetchedCallback(data);
1085-
fetchedCallback = null;
1086-
} else {
1087-
fetched = data;
1088-
}
1089-
}, handleError);\n'''
1070+
if (!fetched) {
1071+
// Note that we don't use await here because we want to execute the
1072+
// the rest of this function immediately.
1073+
fetchRemotePackage(REMOTE_PACKAGE_NAME, REMOTE_PACKAGE_SIZE)
1074+
.then((data) => {
1075+
if (fetchedCallback) {
1076+
fetchedCallback(data);
1077+
fetchedCallback = null;
1078+
} else {
1079+
fetched = data;
1080+
}
1081+
})
1082+
.catch(handleError);
1083+
}\n'''
10901084

10911085
code += '''
10921086
Module['preloadResults'][PACKAGE_NAME] = {fromCache: false};
@@ -1098,7 +1092,7 @@ def generate_js(data_target, data_files, metadata):
10981092
}\n'''
10991093

11001094
ret += '''
1101-
function runWithFS(Module) {\n'''
1095+
async function runWithFS(Module) {\n'''
11021096
ret += code
11031097
ret += '''
11041098
}
@@ -1128,7 +1122,7 @@ def generate_js(data_target, data_files, metadata):
11281122
%(node_support_code)s
11291123
var response = await fetch(metadataUrl);
11301124
if (!response.ok) {
1131-
throw new Error(`${response.status}: ${response.url}`);
1125+
throw `${response.status}: ${response.url}`;
11321126
}
11331127
var json = await response.json();
11341128
return loadPackage(json);

0 commit comments

Comments
 (0)