Setting up a simple runners cluster to parallelize calculations
This commit is contained in:
parent
97f1bb37f9
commit
7899c632f2
|
@ -24,6 +24,7 @@
|
|||
"chai": "^3.5.0",
|
||||
"chalk": "^1.1.3",
|
||||
"co": "^4.6.0",
|
||||
"co-mocha": "^1.1.3",
|
||||
"mocha": "^3.1.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
const cluster = require('cluster');
|
||||
const { length: numCPUs } = require('os').cpus();
|
||||
const { fork } = require('child_process');
|
||||
const Runner = require('./runner');
|
||||
const Layout = require('./layout');
|
||||
|
||||
const workers = [];
|
||||
if (!process.env.CHILD_WORKER) {
|
||||
while (workers.length < numCPUs) {
|
||||
workers.push(fork(__dirname + '/cluster.js', { env: { CHILD_WORKER: 'yup' } }));
|
||||
}
|
||||
} else {
|
||||
let runner;
|
||||
process.on('message', msg => {
|
||||
if (msg.cmd === 'reset') {
|
||||
runner = new Runner(msg.text, msg.options);
|
||||
} else if (msg.cmd === 'run') {
|
||||
const result = runner.typeWith(new Layout(msg.name, msg.config));
|
||||
process.send(Object.assign({}, msg, { cmd: 'result', result }));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = class Cluster {
|
||||
constructor(text, options={}) {
|
||||
workers.forEach(worker => {
|
||||
worker.send({ cmd: 'reset', text, options });
|
||||
worker.on('message', msg => this.receivedMessage(msg));
|
||||
});
|
||||
|
||||
this.waiters = {};
|
||||
}
|
||||
|
||||
*runCollection(layouts) {
|
||||
const promises = layouts.map((layout, index) => {
|
||||
const worker = workers[index % workers.length];
|
||||
return this.scheduleRunWith(layout, worker);
|
||||
});
|
||||
|
||||
return yield Promise.all(promises);
|
||||
}
|
||||
|
||||
scheduleRunWith(layout, worker) {
|
||||
return new Promise(resolve => {
|
||||
const uuid = Date.now() / 10000 + Math.random();
|
||||
this.waiters[uuid] = { resolve, worker };
|
||||
worker.send(Object.assign({ cmd: 'run', uuid }, layout));
|
||||
});
|
||||
}
|
||||
|
||||
receivedMessage(msg) {
|
||||
const { cmd, uuid, result, name, config } = msg;
|
||||
if (cmd === 'result') {
|
||||
const layout = new Layout(name, config);
|
||||
const { worker, resolve } = this.waiters[uuid];
|
||||
delete(this.waiters[uuid]);
|
||||
resolve && resolve({ result, layout });
|
||||
}
|
||||
}
|
||||
};
|
|
@ -0,0 +1,28 @@
|
|||
const Cluster = require('../src/cluster');
|
||||
const { QWERTY, Dvorak, Colemak, Workman } = require('../src/presets');
|
||||
|
||||
const text = global.TEXT_FIXTUE;
|
||||
const layouts = [ QWERTY, Dvorak, Colemak, Workman, QWERTY, Dvorak, Colemak, Workman ];
|
||||
|
||||
describe('Cluster', () => {
|
||||
const cluster = new Cluster(text, {
|
||||
effortLimit: 2000,
|
||||
sameHandPenalty: 0.5,
|
||||
sameFingerPenalty: 5
|
||||
});
|
||||
|
||||
it('allows to run a bunch of layouts', function * () {
|
||||
const results = yield cluster.runCollection(layouts);
|
||||
const data = results.map(result => `${result.layout.name} - ${result.result.position}`);
|
||||
expect(data.sort()).to.eql([
|
||||
"Colemak - 744",
|
||||
"Colemak - 744",
|
||||
"Dvorak - 586",
|
||||
"Dvorak - 586",
|
||||
"QWERTY - 407",
|
||||
"QWERTY - 407",
|
||||
"Workman - 833",
|
||||
"Workman - 833"
|
||||
]);
|
||||
});
|
||||
});
|
|
@ -1,2 +1,19 @@
|
|||
const mocha = require('mocha');
|
||||
const coMocha = require('co-mocha');
|
||||
const { expect } = require('chai');
|
||||
|
||||
global.expect = expect;
|
||||
coMocha(mocha);
|
||||
|
||||
global.TEXT_FIXTUE = `
|
||||
A long time ago in a galaxy far, far away
|
||||
|
||||
It is a period of civil war. Rebel spaceships, striking from a
|
||||
hidden base, have won their first victory against the evil Galactic Empire.
|
||||
During the battle, Rebel spies managed to steal secret plans to the
|
||||
Empire's ultimate weapon, the Death Star, an armored space station
|
||||
with enough power to destroy an entire planet.
|
||||
Pursued by the Empire's sinister agents, Princess Leia races home
|
||||
aboard her starship, custodian of the stolen plans that can save her
|
||||
people and restore freedom to the galaxy...
|
||||
`;
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
const Runner = require('../src/runner');
|
||||
const { QWERTY, Dvorak, Colemak, Workman } = require('../src/presets');
|
||||
const text = `
|
||||
A long time ago in a galaxy far, far away
|
||||
|
||||
It is a period of civil war. Rebel spaceships, striking from a
|
||||
hidden base, have won their first victory against the evil Galactic Empire.
|
||||
During the battle, Rebel spies managed to steal secret plans to the
|
||||
Empire's ultimate weapon, the Death Star, an armored space station
|
||||
with enough power to destroy an entire planet.
|
||||
Pursued by the Empire's sinister agents, Princess Leia races home
|
||||
aboard her starship, custodian of the stolen plans that can save her
|
||||
people and restore freedom to the galaxy...
|
||||
`;
|
||||
const text = global.TEXT_FIXTUE;
|
||||
|
||||
describe('Runner', () => {
|
||||
const runner = new Runner(text, {
|
||||
|
|
13
yarn.lock
13
yarn.lock
|
@ -148,7 +148,14 @@ cli-table@^0.3.1:
|
|||
dependencies:
|
||||
colors "1.0.3"
|
||||
|
||||
co@^4.6.0:
|
||||
co-mocha:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/co-mocha/-/co-mocha-1.1.3.tgz#49bb9c85bcd17e3250f8b84b875dc76668bc41dc"
|
||||
dependencies:
|
||||
co "^4.0.0"
|
||||
is-generator "^1.0.1"
|
||||
|
||||
co@^4.0.0, co@^4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
|
||||
|
||||
|
@ -360,6 +367,10 @@ inherits@~2.0.1, inherits@2:
|
|||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
|
||||
is-generator@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/is-generator/-/is-generator-1.0.3.tgz#c14c21057ed36e328db80347966c693f886389f3"
|
||||
|
||||
is-my-json-valid@^2.12.4:
|
||||
version "2.15.0"
|
||||
resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz#936edda3ca3c211fd98f3b2d3e08da43f7b2915b"
|
||||
|
|
Loading…
Reference in New Issue