Skip to content

Commit 2feb4a0

Browse files
committed
Remove multithreading
1 parent b2519d2 commit 2feb4a0

File tree

9 files changed

+73
-172
lines changed

9 files changed

+73
-172
lines changed

lib/application.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
const { node, npm } = require('./dependencies.js');
44
const { path, events, vm, fs, fsp } = node;
55
const { common } = npm;
6-
76
const security = require('./security.js');
87

98
const SCRIPT_OPTIONS = { timeout: 5000 };

lib/auth.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,5 +124,5 @@ module.exports = () => {
124124
.select('SystemUser', ['Id', 'Password'], { login })
125125
.then(([user]) => user);
126126

127-
return Object.freeze({ start, restore, remove, save, registerUser, getUser });
127+
return { start, restore, remove, save, registerUser, getUser };
128128
};

lib/database.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

3-
const { Pool } = require('pg');
3+
const { npm } = require('./dependencies.js');
4+
const { pg } = npm;
45
const application = require('./application.js');
56

67
const OPERATORS = ['>=', '<=', '<>', '>', '<'];
@@ -47,7 +48,7 @@ const updates = (delta, firstArgIndex = 1) => {
4748

4849
class Database {
4950
constructor(config) {
50-
this.pool = new Pool(config);
51+
this.pool = new pg.Pool(config);
5152
}
5253

5354
query(sql, values) {

lib/logger.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ const COLORS = {
1313
const DATETIME_LENGTH = 19;
1414

1515
class Logger {
16-
constructor(logPath, threadId = 0) {
16+
constructor(logPath) {
1717
this.path = logPath;
1818
const date = new Date().toISOString().substring(0, 10);
19-
const filePath = path.join(logPath, `${date}-W${threadId}.log`);
19+
const filePath = path.join(logPath, `${date}.log`);
2020
this.stream = fs.createWriteStream(filePath, { flags: 'a' });
2121
this.home = path.dirname(this.path);
2222
}

lib/security.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,4 @@ const validatePassword = (password, hash = defaultHash) =>
8181
);
8282
});
8383

84-
module.exports = Object.freeze({ hashPassword, validatePassword });
84+
module.exports = { hashPassword, validatePassword };

lib/semaphore.js

Lines changed: 0 additions & 42 deletions
This file was deleted.

lib/server.js

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
'use strict';
22

33
const { node, npm } = require('./dependencies.js');
4-
const { http, https, worker } = node;
4+
const { http, https } = node;
55
const { common, ws } = npm;
6-
7-
const Semaphore = require('./semaphore.js');
6+
const { Channel } = require('./channel.js');
7+
const { application } = require('./application.js');
88

99
const SHUTDOWN_TIMEOUT = 5000;
1010
const SHORT_TIMEOUT = 500;
@@ -19,61 +19,46 @@ const receiveBody = async (req) => {
1919
};
2020

2121
class Server {
22-
constructor(config, { application, Channel }) {
22+
constructor(config) {
2323
this.config = config;
24-
this.application = application;
25-
this.Channel = Channel;
2624
this.channels = new Map();
27-
const { host, balancer, protocol, ports, concurrency, queue } = config;
28-
this.semaphore = new Semaphore(concurrency, queue.size, queue.timeout);
29-
const { threadId } = worker;
30-
this.balancer = balancer && threadId === 1;
31-
const skipBalancer = balancer ? 1 : 0;
32-
this.port = this.balancer ? balancer : ports[threadId - skipBalancer - 1];
33-
const transport = protocol === 'http' || this.balancer ? http : https;
25+
const { port, host, protocol, cert } = config;
26+
this.port = port;
27+
this.host = host;
28+
this.protocol = protocol;
29+
const transport = protocol === 'http' ? http : https;
3430
const listener = this.listener.bind(this);
35-
this.server = transport.createServer({ ...application.cert }, listener);
31+
this.server = transport.createServer(cert, listener);
3632
this.ws = new ws.Server({ server: this.server });
3733
this.ws.on('connection', async (connection, req) => {
3834
const channel = await new Channel(req, null, connection, application);
3935
connection.on('message', (data) => {
4036
channel.message(data);
4137
});
4238
});
43-
this.protocol = protocol;
44-
this.host = host;
4539
this.server.listen(this.port, host);
4640
}
4741

4842
async listener(req, res) {
49-
const { channels, Channel } = this;
5043
let finished = false;
5144
const { url, connection } = req;
52-
const channel = await new Channel(req, res, null, this.application);
53-
channels.set(connection, channel);
45+
const channel = await new Channel(req, res, null, application);
46+
this.channels.set(connection, channel);
5447

5548
const timer = setTimeout(() => {
5649
if (finished) return;
5750
finished = true;
58-
channels.delete(connection);
51+
this.channels.delete(connection);
5952
channel.error(504);
6053
}, LONG_RESPONSE);
6154

6255
res.on('close', () => {
6356
if (finished) return;
6457
finished = true;
6558
clearTimeout(timer);
66-
channels.delete(connection);
59+
this.channels.delete(connection);
6760
});
6861

69-
if (this.balancer) {
70-
const host = common.parseHost(req.headers.host);
71-
const port = common.sample(this.config.ports);
72-
const { protocol } = this.config;
73-
channel.redirect(`${protocol}://${host}:${port}/`);
74-
return;
75-
}
76-
7762
if (url.startsWith('/api')) this.request(channel);
7863
else channel.static();
7964
}
@@ -117,7 +102,7 @@ class Server {
117102

118103
async close() {
119104
this.server.close((err) => {
120-
if (err) this.application.logger.error(err.stack);
105+
if (err) application.logger.error(err.stack);
121106
});
122107
if (this.channels.size === 0) {
123108
await common.timeout(SHORT_TIMEOUT);

lib/worker.js

Lines changed: 0 additions & 63 deletions
This file was deleted.

server.js

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,61 @@
11
'use strict';
22

3-
const { Worker } = require('worker_threads');
4-
const path = require('path');
5-
3+
const { node } = require('./lib/dependencies.js');
4+
const { fsp, path } = node;
5+
const application = require('./lib/application.js');
66
const Config = require('./lib/config.js');
7-
8-
const PATH = process.cwd();
9-
const CFG_PATH = path.join(PATH, 'application/config');
10-
11-
const options = { trackUnmanagedFds: true };
12-
13-
(async () => {
14-
const config = await new Config(CFG_PATH);
15-
const { balancer, ports = [], workers = {} } = config.server;
16-
const count = ports.length + (balancer ? 1 : 0) + (workers.pool || 0);
17-
let active = count;
18-
const threads = new Array(count);
19-
20-
const start = (id) => {
21-
const worker = new Worker('./lib/worker.js', options);
22-
threads[id] = worker;
23-
worker.on('exit', (code) => {
24-
if (code !== 0) start(id);
25-
else if (--active === 0) process.exit(0);
26-
});
7+
const Logger = require('./lib/logger.js');
8+
const Database = require('./lib/database.js');
9+
const Server = require('./lib/server.js');
10+
const Channel = require('./lib/channel.js');
11+
const initAuth = require('./lib/auth.js');
12+
13+
const loadCert = async (certPath) => {
14+
const key = await fsp.readFile(path.join(certPath, 'key.pem'));
15+
const cert = await fsp.readFile(path.join(certPath, 'cert.pem'));
16+
return { key, cert };
17+
};
18+
19+
const main = async () => {
20+
const configPath = path.join(application.path, 'config');
21+
const config = await new Config(configPath);
22+
const logPath = path.join(application.root, 'log');
23+
const logger = await new Logger(logPath);
24+
Object.assign(application, { config, logger });
25+
26+
const logError = (err) => {
27+
logger.error(err ? err.stack : 'No exception stack available');
2728
};
2829

29-
for (let id = 0; id < count; id++) start(id);
30+
process.on('uncaughtException', logError);
31+
process.on('warning', logError);
32+
process.on('unhandledRejection', logError);
33+
34+
const certPath = path.join(application.path, 'cert');
35+
const cert = await loadCert(certPath).catch(() => {
36+
logError(new Error('Can not load TLS certificates'));
37+
});
38+
39+
application.db = new Database(config.database);
40+
application.auth = initAuth();
41+
application.sandboxInject('auth', application.auth);
3042

31-
const stop = async () => {
32-
console.log();
33-
for (const worker of threads) {
34-
worker.postMessage({ name: 'stop' });
35-
}
43+
const { ports } = config.server;
44+
const options = { cert, application, Channel };
45+
for (const port of ports) {
46+
application.server = new Server(config.server, options);
47+
logger.system(`Listen port ${port}`);
48+
}
49+
50+
await application.init();
51+
logger.system('Application started');
52+
53+
const stop = () => {
54+
process.exit(0);
3655
};
3756

3857
process.on('SIGINT', stop);
3958
process.on('SIGTERM', stop);
40-
})();
59+
};
60+
61+
main();

0 commit comments

Comments
 (0)