Skip to content

Commit

Permalink
new request mechanic for systemjs workers
Browse files Browse the repository at this point in the history
SQUASHED: AUTO-COMMIT-demos-worker-sum-systemjs-worker.js,AUTO-COMMIT-src-worker-meta-worker.js,AUTO-COMMIT-src-worker-systemjs-worker.js,AUTO-COMMIT-test-systemjs-worker-test.js,AUTO-COMMIT-test-systemjs-worker-test-sum-worker.js,AUTO-COMMIT-test-systemjs-worker-test-worker.js,AUTO-COMMIT-test-worker-systemjs-worker-test.js,AUTO-COMMIT-test-worker-systemjs-worker-test-sum-request-worker.js,AUTO-COMMIT-test-worker-systemjs-worker-test-sum-response-worker.js,AUTO-COMMIT-test-worker-systemjs-worker-test-sum-worker.js,
  • Loading branch information
JensLincke committed Nov 14, 2023
1 parent f8b7e2e commit adc4cc8
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 9 deletions.
5 changes: 4 additions & 1 deletion demos/worker/sum-systemjs-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ import {sum} from "./sum.js"

export function onmessage(e) {
postMessage(sum(e.data));
}
}



27 changes: 22 additions & 5 deletions src/worker/meta-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ self.lively4url = self.location.origin + path.join("/");
importScripts("./livelyworker.js")

onmessage = function(evt) {
// console.log("metaworker initial onmessage", evt)

console.log("metaworker initial onmessage", evt)
if (evt.data.message == "load") {
// console.log("meta worker load " + evt.data.url)
console.log("meta worker load " + evt.data.url)
System.import("src/plugin-babel.js").then(() => {
System.import("src/client/preferences.js").then((mod) => {
var Preferences = mod.default
Expand All @@ -21,9 +22,25 @@ onmessage = function(evt) {

System.import(evt.data.url).then((m) => {
postMessage({message: "loaded"})
self.onmessage = (...args) => {
// console.log("metaworker custom onmessage", args)
m.onmessage(...args)
self.onmessage = async (evt) => {
console.log("metaworker onmessage", evt)

if(m.onrequest && evt.data && evt.data.message === "systemjs-worker-request") {
try {
let result = await m.onrequest(evt.data)
// console.log("ON MESSAGE result " + result)
return postMessage({message: "systemjs-worker-response",
name: evt.data.name, id: evt.data.id, response: result})
} catch(e) {
return postMessage({message: "systemjs-worker-response",
name: "error", id: evt.data.id, response: "" + e})
}
}

console.log("metaworker custom onmessage", evt)
if (m.onmessage) {
m.onmessage(evt)
}
}
}).catch((err) => {
console.log("meta worker error ", err)
Expand Down
47 changes: 44 additions & 3 deletions src/worker/systemjs-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,24 @@ import Preferences from "src/client/preferences.js"

export var workers



export default class SystemjsWorker {

static get workers() {
if (!workers) workers = new Set()
return workers
}

newId() {
return this.idCounter++
}


constructor(url) {
/*MD The meta-worker is the actual worker, that is generic will load the actual systemjs module, which contains the client code MD*/
this.idCounter = 1
this.resolveRequestForId = new Map()
this.metaworker = new Worker("src/worker/meta-worker.js");
/*MD ## bootstrap onmessage MD*/
// console.log("sytemjs-worker new: " + url)
Expand All @@ -21,7 +30,7 @@ export default class SystemjsWorker {


setTimeout(() => {
if (!isLoaded) reject("timeout")
if (!isLoaded) reject("timeout while loading systemjs")
}, 10000) // 10s then timeout?

/*MD ### Setup: install a message for loading, that will be rpelaced later MD*/
Expand All @@ -35,9 +44,16 @@ export default class SystemjsWorker {
// console.log("worker loaded", url)

/*MD ### Important: here the actual client message is installed MD*/
this.metaworker.onmessage = (msg) => {
this.metaworker.onmessage = (evt) => {
console.log("systemjs-worker.js ON MESSAGE", evt)
let msg = evt.data
// check if we handle it ourself
if (msg && msg.message === "systemjs-worker-response") {
return this.handleRequest(msg)
}

// console.log(`systemjs-worker.js metaworker.onmessage (${url})` )
this.onmessage(msg)
this.onmessage(evt)
}
isLoaded = true
resolve(true) // worker should accept postMessages now...
Expand All @@ -54,6 +70,31 @@ export default class SystemjsWorker {
onmessage(evt) {
// do nothing
}

handleRequest(msg) {
console.log("handleRequest ", msg)
var resolve = this.resolveRequestForId.get(msg.id)
if (!resolve) {
throw new Error("No resolve func for message " + msg.name + ", " + msg.id + ", " + msg.response)
}
this.resolveRequestForId.set(msg.id, null)
resolve(msg.response)
}

async request(name, data, timeout=1000) {

var id = this.newId()
var promise = new Promise((resolve, reject) => {
this.resolveRequestForId.set(id, resolve)
this.postMessage({message: "systemjs-worker-request", id: id, name: name, arguments: data})
var start = performance.now()
setTimeout(() => {
var unhandledRequestResolve = this.resolveRequestForId.get(id)
if (unhandledRequestResolve) reject({error: "request timeout after " + (performance.now() - start) + "ms"})
}, timeout)
})
return promise
}

terminate() {
this.metaworker.terminate()
Expand Down
26 changes: 26 additions & 0 deletions test/worker/systemjs-worker-test-sum-request-worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@



export async function onrequest(msg) {
if (msg.name === "sum") {
var array = msg.arguments
let result = array[0] + array[1]

return result
}
throw new Error("request not understood: " + msg)
}


// export function onmessage(evt) {
// if(evt.data && evt.data.message === "systemjs-worker-request") {
// if (evt.data.name === "sum") {
// var array = evt.data.arguments
// let result = array[0] + array[1]
// // console.log("ON MESSAGE result " + result)
// return postMessage({message: "systemjs-worker-response", name: evt.data.name, id: evt.data.id, response: result})
// }
// return postMessage({error: "unhandled systemjs-worker-request " + evt})
// }
// return postMessage({error: "could not handle message " + evt})
// }
7 changes: 7 additions & 0 deletions test/worker/systemjs-worker-test-sum-worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@


export function onmessage(evt) {
let result = evt.data[0] + evt.data[1]

postMessage(result)
}
54 changes: 54 additions & 0 deletions test/worker/systemjs-worker-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@

import SystemjsWorker from "src/worker/systemjs-worker.js"

import {expect} from 'src/external/chai.js';

describe('SystemJSWorker', () => {


describe('onmessage and postMessage', () => {
let myworker
before(async () => {
myworker = new SystemjsWorker(lively4url + "/test/worker/systemjs-worker-test-sum-worker.js")

await myworker.loaded
})

it('sums', async () => {
var wasrun = false
myworker.onmessage = (evt) => {
wasrun = true
expect(evt.data).equals(7)
}
myworker.postMessage([3, 4]);

await lively.sleep(1) // not directly connected yet

expect(wasrun, "wasrun").equals(true)

})
after(() => {
myworker.terminate()
})

})

describe('request', () => {
let myworker
before(async () => {
myworker = new SystemjsWorker(lively4url + "/test/worker/systemjs-worker-test-sum-request-worker.js")

await myworker.loaded
})

it('sums', async () => {

var result = await myworker.request("sum", [3, 4]);

// expect(result, "result").equals(7)
})
after(() => {
myworker.terminate()
})
})
});

0 comments on commit adc4cc8

Please sign in to comment.