From 397d84c986c66c83b3da285a3cb5664313d6da44 Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Sun, 20 Jun 2021 23:38:19 -0400 Subject: [PATCH] change minion dispatch model which was causing odd chromium internal memory leaks --- src/kiri/minion.js | 28 ++++++++++++++-------------- src/kiri/slicer.js | 3 +-- src/kiri/worker.js | 25 +++++++++++++++++++++---- 3 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/kiri/minion.js b/src/kiri/minion.js index 32c7ab8d..318f4131 100644 --- a/src/kiri/minion.js +++ b/src/kiri/minion.js @@ -20,7 +20,7 @@ self.alert = function(o) { self.onmessage = function(msg) { let data = msg.data; let cmd = data.cmd; - (funcs[cmd] || funcs.bad)(data); + (funcs[cmd] || funcs.bad)(data, data.seq); }; function reply(msg, direct) { @@ -28,24 +28,24 @@ function reply(msg, direct) { } const funcs = { - union: data => { + union: (data, seq) => { if (!(data.polys && data.polys.length)) { - reply({union: CODEC.encode([])}); + reply({ seq, union: CODEC.encode([]) }); return; } let polys = CODEC.decode(data.polys); let union = POLY.union(polys, data.minarea || 0, true); - reply({union: CODEC.encode(union)}); + reply({ seq, union: CODEC.encode(union) }); }, - topShells: data => { + topShells: (data, seq) => { let top = CODEC.decode(data.top, {full: true}); let {z, count, offset1, offsetN, fillOffset, opt} = data; KIRI.driver.FDM.share.doTopShells(z, top, count, offset1, offsetN, fillOffset, opt); - reply({top: CODEC.encode(top, {full: true})}); + reply({ seq, top: CODEC.encode(top, {full: true}) }); }, - fill: data => { + fill: (data, seq) => { let polys = CODEC.decode(data.polys); let { angle, spacing, minLen, maxLen } = data; let fill = POLY.fillArea(polys, angle, spacing, [], minLen, maxLen); @@ -57,10 +57,10 @@ const funcs = { arr[i++] = pt.z; arr[i++] = pt.index; } - reply({ fill: arr }, [ arr.buffer ]); + reply({ seq, fill: arr }, [ arr.buffer ]); }, - clip: data => { + clip: (data, seq) => { let clip = new clib.Clipper(); let ctre = new clib.PolyTree(); let clips = []; @@ -74,10 +74,10 @@ const funcs = { } } - reply({ clips }); + reply({ seq, clips }); }, - sliceBucket: data => { + sliceBucket: (data, seq) => { let { points, slices, options } = data; let i = 0, p = 0, realp = new Array(points.length / 3); while (i < points.length) { @@ -90,10 +90,10 @@ const funcs = { tops: KIRI.slicer.sliceZ(slice.z, realp, options).tops }); } - reply({ output: CODEC.encode(output) }); + reply({ seq, output: CODEC.encode(output) }); }, - bad: data => { - reply({error: "invalid command"}); + bad: (data, seq) => { + reply({ seq, error: "invalid command" }); } }; diff --git a/src/kiri/slicer.js b/src/kiri/slicer.js index 5fb67091..0af088c7 100644 --- a/src/kiri/slicer.js +++ b/src/kiri/slicer.js @@ -301,8 +301,7 @@ }); function bucketZ(index, z, height, thick) { - let bucket = buckets[Math.floor(z * zScale)]; - bucket.slices.push({ + buckets[Math.floor(z * zScale)].slices.push({ index, z, height, thick }); } diff --git a/src/kiri/worker.js b/src/kiri/worker.js index 31336c2d..148ff468 100644 --- a/src/kiri/worker.js +++ b/src/kiri/worker.js @@ -17,7 +17,9 @@ let BASE = self.base, wgroup = {}, wcache = {}, minions = [], - minionq = []; + minionq = [], + minifns = {}, + miniseq = 0; // catch clipper alerts and convert to console messages self.alert = function(o) { @@ -26,8 +28,21 @@ self.alert = function(o) { // start concurrent workers (minions) if (concurrent) { + function dispatch(msg) { + let data = msg.data; + let seq = data.seq; + let fn = minifns[seq]; + if (!fn) { + throw `missing dispatch ${seq}`; + } + delete minifns[seq]; + fn(data); + } + for (let i=0; i < concurrent; i++) { - minions.push(new Worker(`/code/minion.js?${self.kiri.version}`)); + let minion = new Worker(`/code/minion.js?${self.kiri.version}`); + minion.onmessage = dispatch; + minions.push(minion); } console.log(`kiri | init mini | ${KIRI.version || "rogue"} | ${concurrent}`); } @@ -153,9 +168,11 @@ KIRI.minions = { if (minions.length && minionq.length) { let qrec = minionq.shift(); let minion = minions.shift(); - minion.onmessage = (msg) => { + let seq = miniseq++; + qrec.work.seq = seq; + minifns[seq] = (data) => { + qrec.ondone(data); minions.push(minion); - qrec.ondone(msg.data); minwork.kick(); }; minion.postMessage(qrec.work, qrec.direct);