-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathserver.js
55 lines (50 loc) · 1.65 KB
/
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
'use strict';
const http = require('http');
const { Worker } = require('worker_threads');
const workerPool = [ // Start a pool of four workers
new Worker('./worker.js'),
new Worker('./worker.js'),
new Worker('./worker.js'),
new Worker('./worker.js'),
];
const waiting = [];
http.createServer((req, res) => {
let body = '';
req.setEncoding('utf8'); // Receive strings rather than binary data
req.on('data', chunk => body += chunk);
req.on('end', () => {
let dataAsUint8Array;
try {
dataAsUint8Array = new Uint8Array(JSON.parse(body));
// Fix the length at 81 = 9*9 fields so that we are not DoS’ed through
// overly long input data.
dataAsUint8Array = dataAsUint8Array.slice(0, 81);
} catch (err) {
res.writeHead(400);
res.end(`Failed to parse body: ${err}`);
return;
}
res.writeHead(200, {
'Content-Type': 'application/json'
});
if (workerPool.length > 0) {
handleRequest(res, dataAsUint8Array, workerPool.shift());
} else {
// Queue up requests when no worker is available.
// The function is waiting for a worker to be assigned.
waiting.push((worker) => handleRequest(res, dataAsUint8Array, worker));
}
});
}).listen(3000);
function handleRequest(res, sudokuData, worker) {
worker.postMessage(sudokuData);
worker.once('message', (solutionData) => {
res.end(JSON.stringify([...solutionData]));
// If requests are waiting, reuse the current worker to handle the queued
// request. Add the worker to pool if no requests are queued.
if (waiting.length > 0)
waiting.shift()(worker);
else
workerPool.push(worker);
});
}