Skip to content

Commit

Permalink
Merge pull request #1737 from finos/worker-single-thread-fallback
Browse files Browse the repository at this point in the history
Allow `@finos/perspective` to run in single-threaded mode
  • Loading branch information
texodus authored Mar 4, 2022
2 parents 93900fd + 0b81915 commit c3122ef
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 9 deletions.
4 changes: 1 addition & 3 deletions packages/perspective/src/js/perspective.browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,7 @@ class WebWorkerClient extends Client {
let _worker;
const msg = {cmd: "init", config: get_config()};
if (typeof WebAssembly === "undefined") {
throw new Error(
"WebAssembly not supported. Support for ASM.JS has been removed as of 0.3.1."
);
throw new Error("WebAssembly not supported.");
} else {
[_worker, msg.buffer] = await Promise.all([
_override().worker(),
Expand Down
86 changes: 80 additions & 6 deletions tools/perspective-build/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,47 @@ exports.WorkerPlugin = function WorkerPlugin(inline) {
return {
contents: `
import worker from ${JSON.stringify(args.path)};
function make_host(a, b) {
function addEventListener(type, callback) {
a.push(callback);
}
function postMessage(msg) {
if (Object.keys(msg).length > 0) {
for (const listener of b) {
listener({data: msg});
}
}
}
return {
addEventListener,
postMessage,
location: {href: ""}
}
}
function run_single_threaded(code, e) {
console.error("Running perspective in single-threaded mode due to error initializing Web Worker:", e);
let f = Function("const self = arguments[0];" + code);
const workers = [];
const mains = [];
f(make_host(workers, mains));
return make_host(mains, workers);
}
export const initialize = async function () {
const blob = new Blob([worker], {type: 'application/javascript'});
const url = URL.createObjectURL(blob);
return new Worker(url, {type: "module"});
if (window.location.protocol.startsWith("file")) {
return run_single_threaded(worker, "file:// protocol does not support Web Workers");
}
try {
const blob = new Blob([worker], {type: 'application/javascript'});
const url = URL.createObjectURL(blob);
return new Worker(url, {type: "module"});
} catch (e) {
return run_single_threaded(worker, e);
}
};
export default initialize;
Expand All @@ -64,12 +101,49 @@ exports.WorkerPlugin = function WorkerPlugin(inline) {
return code;
};
function make_host(a, b) {
function addEventListener(type, callback) {
a.push(callback);
}
function postMessage(msg) {
if (Object.keys(msg).length > 0) {
for (const listener of b) {
listener({data: msg});
}
}
}
return {
addEventListener,
postMessage,
location: {href: ""}
}
}
function run_single_threaded(code, e) {
console.error("Running perspective in single-threaded mode due to error initializing Web Worker:", e);
let f = Function("const self = arguments[0];" + code);
const workers = [];
const mains = [];
f(make_host(workers, mains));
return make_host(mains, workers);
}
const code_promise = get_worker_code();
export const initialize = async function () {
const code = await code_promise;
const blob = new Blob([code], {type: 'application/javascript'});
const url2 = URL.createObjectURL(blob);
return new Worker(url2, {type: "module"});
if (window.location.protocol.startsWith("file")) {
return run_single_threaded(code, "file:// protocol does not support Web Workers");
}
try {
const blob = new Blob([code], {type: 'application/javascript'});
const url = URL.createObjectURL(blob);
return new Worker(url, {type: "module"});
} catch (e) {
return run_single_threaded(code, e);
}
};
export default initialize;
Expand Down

0 comments on commit c3122ef

Please sign in to comment.