@koeroesi86/node-worker-express 22.3.12-fd2e588 → 23.3.4361459321-main
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/constants/index.d.ts +11 -0
- package/dist/index-aad82b3f.js +15 -0
- package/dist/index-aad82b3f.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +446 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/bodyParser.d.ts +5 -0
- package/dist/middleware/index.d.ts +19 -0
- package/dist/staticWorker.d.ts +3 -0
- package/dist/staticWorker.js +194 -0
- package/dist/staticWorker.js.map +1 -0
- package/dist/types/index.d.ts +41 -0
- package/dist/utils/constructWsMessage.d.ts +3 -0
- package/dist/utils/getClientIp.d.ts +3 -0
- package/dist/utils/isWebSocket.d.ts +3 -0
- package/dist/utils/parseWsMessage.d.ts +3 -0
- package/dist/utils/workerPool.d.ts +19 -0
- package/dist/workerInvoke.d.ts +1 -0
- package/dist/workerInvoke.js +54 -0
- package/dist/workerInvoke.js.map +1 -0
- package/package.json +8 -3
- package/rollup.config.js +12 -0
- package/.travis.yml +0 -17
- package/constants/index.js +0 -12
- package/examples/public/favicon.ico +0 -0
- package/examples/public/websocket/worker.js +0 -60
- package/examples/public/worker.js +0 -42
- package/examples/server.js +0 -29
- package/examples/staticWorker.js +0 -237
- package/index.d.ts +0 -64
- package/index.js +0 -3
- package/middleware/bodyParser.js +0 -36
- package/middleware/index.js +0 -288
- package/middleware/workerInvoke.js +0 -54
- package/nodemon.json +0 -6
- package/scripts/version.js +0 -9
- package/utils/constructWsMessage.js +0 -27
- package/utils/getClientIp.js +0 -71
- package/utils/isWebSocket.js +0 -16
- package/utils/parseWsMessage.js +0 -25
- package/utils/workerPool.js +0 -101
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TODO: improve
|
|
3
|
-
* @param {String} text
|
|
4
|
-
* @returns {Buffer}
|
|
5
|
-
*/
|
|
6
|
-
const constructWsMessage = text => {
|
|
7
|
-
const jsonByteLength = Buffer.byteLength(text);
|
|
8
|
-
// Note: we're not supporting > 65535 byte payloads at this stage
|
|
9
|
-
const lengthByteCount = jsonByteLength < 126 ? 0 : 2;
|
|
10
|
-
const payloadLength = lengthByteCount === 0 ? jsonByteLength : 126;
|
|
11
|
-
const buffer = Buffer.alloc(2 + lengthByteCount + jsonByteLength);
|
|
12
|
-
// Write out the first byte, using opcode `1` to indicate that the message
|
|
13
|
-
// payload contains text data
|
|
14
|
-
buffer.writeUInt8(0b10000001, 0);
|
|
15
|
-
buffer.writeUInt8(payloadLength, 1);
|
|
16
|
-
// Write the length of the JSON payload to the second byte
|
|
17
|
-
let payloadOffset = 2;
|
|
18
|
-
if (lengthByteCount > 0) {
|
|
19
|
-
buffer.writeUInt16BE(jsonByteLength, 2);
|
|
20
|
-
payloadOffset += lengthByteCount;
|
|
21
|
-
}
|
|
22
|
-
// Write the JSON data to the data buffer
|
|
23
|
-
buffer.write(text, payloadOffset);
|
|
24
|
-
return buffer;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
module.exports = constructWsMessage;
|
package/utils/getClientIp.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @param {module:http~IncomingMessage} request
|
|
3
|
-
* @returns {string}
|
|
4
|
-
*/
|
|
5
|
-
const getClientIp = request => {
|
|
6
|
-
if (request.headers['x-client-ip']) {
|
|
7
|
-
return request.headers['x-client-ip'];
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
if (request.headers['x-forwarded-for']) {
|
|
11
|
-
return request.headers['x-forwarded-for'];
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
if (request.headers['cf-connecting-ip']) {
|
|
15
|
-
return request.headers['cf-connecting-ip'];
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
if (request.headers['fastly-client-ip']) {
|
|
19
|
-
return request.headers['fastly-client-ip'];
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (request.headers['true-client-ip']) {
|
|
23
|
-
return request.headers['true-client-ip'];
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (request.headers['x-real-ip']) {
|
|
27
|
-
return request.headers['x-real-ip'];
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (request.headers['x-cluster-client-ip']) {
|
|
31
|
-
return request.headers['x-cluster-client-ip'];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (request.headers['x-forwarded']) {
|
|
35
|
-
return request.headers['x-forwarded'];
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (request.headers['forwarded-for']) {
|
|
39
|
-
return request.headers['forwarded-for'];
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (request.headers.forwarded) {
|
|
43
|
-
return request.headers.forwarded;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (request.connection) {
|
|
47
|
-
if (request.connection.remoteAddress) {
|
|
48
|
-
return request.connection.remoteAddress;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (request.connection.socket && request.connection.socket.remoteAddress) {
|
|
52
|
-
return request.connection.socket.remoteAddress;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (request.socket && request.socket.remoteAddress) {
|
|
57
|
-
return request.socket.remoteAddress;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (request.info && request.info.remoteAddress) {
|
|
61
|
-
return request.info.remoteAddress;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (request.requestContext && request.requestContext.identity && request.requestContext.identity.sourceIp) {
|
|
65
|
-
return request.requestContext.identity.sourceIp;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return '';
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
module.exports = getClientIp;
|
package/utils/isWebSocket.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @param {module:http~IncomingMessage} request
|
|
3
|
-
* @returns {boolean}
|
|
4
|
-
*/
|
|
5
|
-
const isWebSocket = request => {
|
|
6
|
-
if (request.method !== 'GET') return false;
|
|
7
|
-
|
|
8
|
-
const connection = request.headers.connection || '';
|
|
9
|
-
const upgrade = request.headers.upgrade || '';
|
|
10
|
-
|
|
11
|
-
return request.method === 'GET' &&
|
|
12
|
-
connection.toLowerCase().split(/ *, */).indexOf('upgrade') >= 0 &&
|
|
13
|
-
upgrade.toLowerCase() === 'websocket';
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
module.exports = isWebSocket;
|
package/utils/parseWsMessage.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TODO: improve
|
|
3
|
-
* @param {Buffer} data
|
|
4
|
-
* @returns {string}
|
|
5
|
-
*/
|
|
6
|
-
const parseWsMessage = data => {
|
|
7
|
-
const dl = data[1] & 127;
|
|
8
|
-
let ifm = 2;
|
|
9
|
-
if (dl === 126) {
|
|
10
|
-
ifm = 4;
|
|
11
|
-
} else if (dl === 127) {
|
|
12
|
-
ifm = 10;
|
|
13
|
-
}
|
|
14
|
-
let i = ifm + 4;
|
|
15
|
-
const masks = data.slice(ifm, i);
|
|
16
|
-
let index = 0;
|
|
17
|
-
let output = "";
|
|
18
|
-
const l = data.length;
|
|
19
|
-
while (i < l) {
|
|
20
|
-
output += String.fromCharCode(data[i++] ^ masks[index++ % 4]);
|
|
21
|
-
}
|
|
22
|
-
return output;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
module.exports = parseWsMessage;
|
package/utils/workerPool.js
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
const { v4: uuid } = require('uuid');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const Worker = require('@koeroesi86/node-worker');
|
|
4
|
-
|
|
5
|
-
/** @var {WorkerPool[]} */
|
|
6
|
-
const pools = [];
|
|
7
|
-
|
|
8
|
-
process.once('exit', () => {
|
|
9
|
-
pools.forEach(pool => pool.onClose());
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
const createWorkerCommand = workerPath => {
|
|
13
|
-
const ext = path.extname(workerPath);
|
|
14
|
-
switch (ext) {
|
|
15
|
-
case '.js':
|
|
16
|
-
default:
|
|
17
|
-
return `node --expose-gc ${path.resolve(__dirname, '../middleware/workerInvoke.js')} ${workerPath}`;
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
class WorkerPool {
|
|
22
|
-
constructor({
|
|
23
|
-
overallLimit = 0,
|
|
24
|
-
idleCheckTimeout = 5,
|
|
25
|
-
onExit = () => {
|
|
26
|
-
}
|
|
27
|
-
}) {
|
|
28
|
-
this.overallLimit = overallLimit;
|
|
29
|
-
this.idleCheckTimeout = idleCheckTimeout;
|
|
30
|
-
this.onExit = onExit;
|
|
31
|
-
this.workers = {};
|
|
32
|
-
pools.push(this);
|
|
33
|
-
|
|
34
|
-
this._creating = false;
|
|
35
|
-
|
|
36
|
-
this.getWorker = this.getWorker.bind(this);
|
|
37
|
-
this.onClose = this.onClose.bind(this);
|
|
38
|
-
this.getNonBusyId = this.getNonBusyId.bind(this);
|
|
39
|
-
this.getWorkerCount = this.getWorkerCount.bind(this);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
onClose() {
|
|
43
|
-
Object.keys(this.workers).forEach(workerPath => {
|
|
44
|
-
const current = this.workers[workerPath];
|
|
45
|
-
Object.keys(current).forEach(id => {
|
|
46
|
-
current[id].terminate();
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
getNonBusyId(workerPath) {
|
|
52
|
-
return this.workers[workerPath] ? Object.keys(this.workers[workerPath] || {}).find(id => {
|
|
53
|
-
return !this.workers[workerPath][id].busy;
|
|
54
|
-
}) : undefined;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
getWorkerCountForPath(p) {
|
|
58
|
-
return this.workers[p] ? Object.keys(this.workers[p]).length : 0;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
getWorkerCount() {
|
|
62
|
-
return Object.keys(this.workers).reduce((result, current) => this.getWorkerCountForPath(current) + result, 0);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
isBeyondLimit(workerPath, limit) {
|
|
66
|
-
return (this.workers[workerPath] && limit > 0 && this.getWorkerCountForPath(workerPath) >= limit)
|
|
67
|
-
|| (this.overallLimit > 0 && this.getWorkerCount() >= this.overallLimit);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async getWorker(workerPath, options = {}, limit = 0) {
|
|
71
|
-
const nonBusyId = this.getNonBusyId(workerPath);
|
|
72
|
-
// TODO: tidy up
|
|
73
|
-
if (nonBusyId !== undefined) {
|
|
74
|
-
return this.workers[workerPath][nonBusyId];
|
|
75
|
-
} else if (this.isBeyondLimit(workerPath, limit) || this._creating) {
|
|
76
|
-
await new Promise(r => setTimeout(r, this.idleCheckTimeout));
|
|
77
|
-
return this.getWorker(workerPath, options, limit);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
this._creating = true;
|
|
81
|
-
const id = uuid();
|
|
82
|
-
const instance = new Worker(createWorkerCommand(workerPath), options);
|
|
83
|
-
|
|
84
|
-
if (!this.workers[workerPath]) {
|
|
85
|
-
this.workers[workerPath] = {};
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
instance.addEventListenerOnce('close', code => {
|
|
89
|
-
this.workers[workerPath][id] = null;
|
|
90
|
-
delete this.workers[workerPath][id];
|
|
91
|
-
this.onExit(code, workerPath, id);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
this.workers[workerPath][id] = instance;
|
|
95
|
-
|
|
96
|
-
this._creating = false;
|
|
97
|
-
return instance;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
module.exports = WorkerPool;
|