Don't use a worker for downloading projects

We are not doing anything else on the main thread that would
justify spinning up a Worker. They are just another source of
possible error.
This commit is contained in:
Muffin 2024-07-24 00:29:48 -05:00
parent f60fe5d16f
commit ac86917ca9
6 changed files with 20 additions and 118 deletions

7
package-lock.json generated
View File

@ -23,7 +23,6 @@
"@turbowarp/scratch-svg-renderer": "^1.0.0-202401111326-62c0f26",
"babel-jest": "^27.4.5",
"babel-loader": "^8.2.3",
"comlink": "^4.3.1",
"copy-webpack-plugin": "^6.4.1",
"cross-env": "^7.0.3",
"css-loader": "^5.2.7",
@ -4719,12 +4718,6 @@
"node": ">= 0.8"
}
},
"node_modules/comlink": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/comlink/-/comlink-4.4.1.tgz",
"integrity": "sha512-+1dlx0aY5Jo1vHy/tSsIGpSkN4tS9rZSW8FIhG0JH/crs9wwweswIo/POr451r7bZww3hFbPAKnTpimzL/mm4Q==",
"dev": true
},
"node_modules/commander": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",

View File

@ -47,7 +47,6 @@
"@turbowarp/scratch-svg-renderer": "^1.0.0-202401111326-62c0f26",
"babel-jest": "^27.4.5",
"babel-loader": "^8.2.3",
"comlink": "^4.3.1",
"copy-webpack-plugin": "^6.4.1",
"cross-env": "^7.0.3",
"css-loader": "^5.2.7",

View File

@ -1,11 +0,0 @@
const loaderUtils = require('loader-utils');
module.exports.pitch = function (request) {
// extra whitespace here won't matter
return `
import {expose} from 'comlink';
import * as mod from ${loaderUtils.stringifyRequest(this, request)};
postMessage('ready');
expose(mod);
`;
};

View File

@ -1,77 +0,0 @@
const SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin');
const path = require('path');
const loaderUtils = require('loader-utils');
module.exports.pitch = function (request) {
if (this.target !== 'web') {
return `
import * as mod from ${loaderUtils.stringifyRequest(this, request)};
const shimmedCreateWorker = () => {
return {
worker: mod,
terminate: () => {}
};
};
export default shimmedCreateWorker;
`;
}
const compilerOptions = this._compiler.options || {};
const options = {
filename: compilerOptions.output.filename.replace('.js', '.worker.js')
};
this.cacheable(false);
const callback = this.async();
const compiler = this._compilation.createChildCompiler('p4 worker loader', options);
const exposeLoader = path.resolve(__dirname, 'auto-comlink-expose-loader.js');
new SingleEntryPlugin(
this.context,
`!!${exposeLoader}!${request}`,
path.parse(this.resourcePath).name
).apply(compiler);
compiler.runAsChild((err, entries, compilation) => {
if (err) return callback(err);
const file = entries[0].files[0];
const inline = !!process.env.STANDALONE;
// extra whitespace here won't matter
const source = `
import {wrap} from 'comlink';
const createWorker = () => {
${inline ? `
const source = ${JSON.stringify(compilation.assets[file].source())};
const blob = new Blob([source]);
const url = URL.createObjectURL(blob);
const worker = new Worker(url);
URL.revokeObjectURL(url);
` : `
const worker = new Worker(__webpack_public_path__ + ${JSON.stringify(file)});
`}
return new Promise((resolve, reject) => {
const terminate = () => {
worker.terminate();
};
const onMessage = (e) => {
if (e.data === 'ready') {
cleanup();
resolve({
worker: wrap(worker),
terminate
});
}
};
const onError = () => {
cleanup();
reject(new Error(${JSON.stringify(`Worker ${file} failed to load. Usually this will be fixed after refreshing.`)}));
};
const cleanup = () => {
worker.removeEventListener('message', onMessage);
worker.removeEventListener('error', onError);
};
worker.addEventListener('message', onMessage);
worker.addEventListener('error', onError);
});
};
export default createWorker;
`;
return callback(null, source);
});
};

View File

@ -70,10 +70,12 @@ const mutateScratch3InPlace = (projectData) => {
optimizeSb3Json(projectData);
};
export const downloadProject = async (projectData, progressCallback = () => {}) => {
export const downloadProject = async (projectData, progressCallback = () => {}, signal) => {
let analysis = unknownAnalysis();
const options = {
signal,
onProgress(type, loaded, total) {
progressCallback(type, loaded, total);
},

View File

@ -1,30 +1,26 @@
import {transfer, proxy} from 'comlink';
import createDownloadWorker from '../build/p4-worker-loader!./download-project';
import {readAsArrayBuffer} from '../common/readers';
import request from '../common/request';
import {AbortError} from '../common/errors';
const downloadProject = async (buffer, progressCallback) => {
const {worker, terminate} = await createDownloadWorker();
let terminateAndReject;
const downloadPromise = new Promise((resolve, reject) => {
worker.downloadProject(transfer(buffer, [buffer]), proxy(progressCallback))
.then((res) => {
terminate();
resolve(res);
})
.catch((err) => {
terminate();
reject(err)
});
terminateAndReject = () => {
terminate();
reject(new AbortError());
};
});
const controller = typeof AbortController === 'function' && new AbortController();
const downloadProject = await import(/* webpackChunkName: "downloader" */ './download-project.js');
let reject;
return {
promise: downloadPromise,
terminate: terminateAndReject
promise: new Promise((_resolve, _reject) => {
reject = _reject;
downloadProject.downloadProject(buffer, progressCallback, controller && controller.signal)
.then(result => _resolve(result))
.catch(err => _reject(err));
}),
terminate: () => {
reject(new AbortError());
if (controller) {
controller.abort();
}
}
};
};