@eventista/ticketing-common 1.0.0 → 1.0.2
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/dist/cluster/config/cluster.config.d.ts +8 -0
- package/dist/cluster/config/cluster.config.js +8 -0
- package/dist/cluster/config/cluster.config.js.map +1 -0
- package/dist/cluster/index.d.ts +2 -0
- package/dist/cluster/index.js +19 -0
- package/dist/cluster/index.js.map +1 -0
- package/dist/cluster/modules/cluster.module.d.ts +2 -0
- package/dist/cluster/modules/cluster.module.js +22 -0
- package/dist/cluster/modules/cluster.module.js.map +1 -0
- package/dist/cluster/services/cluster.service.d.ts +7 -0
- package/dist/cluster/services/cluster.service.js +63 -0
- package/dist/cluster/services/cluster.service.js.map +1 -0
- package/dist/database/mongodb/mongodb.service.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/cluster/config/cluster.config.ts +6 -0
- package/src/cluster/index.ts +2 -0
- package/src/cluster/modules/cluster.module.ts +9 -0
- package/src/cluster/services/cluster.service.ts +76 -0
- package/src/database/mongodb/mongodb.service.ts +3 -3
package/package.json
CHANGED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { CustomLogger } from 'src/logger';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
// Import node:cluster và node:os
|
|
6
|
+
const cluster = require('node:cluster');
|
|
7
|
+
const { cpus } = require('node:os');
|
|
8
|
+
|
|
9
|
+
@Injectable()
|
|
10
|
+
export class ClusterService {
|
|
11
|
+
private logger: CustomLogger;
|
|
12
|
+
|
|
13
|
+
constructor() {
|
|
14
|
+
this.logger = new CustomLogger('ClusterService');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Khởi động ứng dụng với chế độ cluster hoặc đơn luồng dựa trên cấu hình
|
|
19
|
+
* @param bootstrapFunction Hàm khởi động ứng dụng
|
|
20
|
+
*/
|
|
21
|
+
public startApplication(bootstrapFunction: () => Promise<void>): void {
|
|
22
|
+
// Lấy giá trị ENABLE_CLUSTER từ biến môi trường, mặc định là 'false'
|
|
23
|
+
const enableCluster = process.env.ENABLE_CLUSTER?.toLowerCase() === 'true';
|
|
24
|
+
|
|
25
|
+
if (enableCluster && cluster.isPrimary) {
|
|
26
|
+
this.startClusterMode();
|
|
27
|
+
} else {
|
|
28
|
+
this.startSingleProcessMode(bootstrapFunction, enableCluster);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Khởi động ứng dụng trong chế độ cluster
|
|
34
|
+
*/
|
|
35
|
+
private startClusterMode(): void {
|
|
36
|
+
this.logger.log(`Cluster mode enabled. Primary ${process.pid} is running`);
|
|
37
|
+
|
|
38
|
+
// Fork workers for each CPU
|
|
39
|
+
const numCPUs = cpus().length;
|
|
40
|
+
|
|
41
|
+
// Có thể giới hạn số lượng worker thông qua biến môi trường
|
|
42
|
+
const maxWorkers = parseInt(process.env.MAX_WORKERS || String(numCPUs), 10);
|
|
43
|
+
const workerCount = Math.min(numCPUs, maxWorkers);
|
|
44
|
+
|
|
45
|
+
this.logger.log(`Starting ${workerCount} workers out of ${numCPUs} available CPUs`);
|
|
46
|
+
|
|
47
|
+
for (let i = 0; i < workerCount; i++) {
|
|
48
|
+
cluster.fork();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
cluster.on('exit', (worker, code, signal) => {
|
|
52
|
+
this.logger.warn(`Worker ${worker.process.pid} died with code ${code} and signal ${signal}`);
|
|
53
|
+
// Thay thế worker đã chết
|
|
54
|
+
this.logger.log('Forking a new worker...');
|
|
55
|
+
cluster.fork();
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Khởi động ứng dụng trong chế độ đơn luồng hoặc như một worker
|
|
61
|
+
* @param bootstrapFunction Hàm khởi động ứng dụng
|
|
62
|
+
* @param isWorker Có phải là worker trong chế độ cluster không
|
|
63
|
+
*/
|
|
64
|
+
private startSingleProcessMode(bootstrapFunction: () => Promise<void>, isWorker: boolean): void {
|
|
65
|
+
bootstrapFunction().catch(err => {
|
|
66
|
+
this.logger.error('Failed to start application', err);
|
|
67
|
+
process.exit(1);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (isWorker) {
|
|
71
|
+
this.logger.log(`Worker ${process.pid} started`);
|
|
72
|
+
} else {
|
|
73
|
+
this.logger.log(`Running in single process mode. Process ${process.pid} started`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -9,14 +9,14 @@ export class MongodbService implements OnModuleInit {
|
|
|
9
9
|
constructor(
|
|
10
10
|
@InjectConnection()
|
|
11
11
|
private readonly connection: Connection,
|
|
12
|
-
) {
|
|
12
|
+
) {}
|
|
13
13
|
|
|
14
14
|
async onModuleInit() {
|
|
15
15
|
try {
|
|
16
16
|
// Kiểm tra kết nối khi khởi động
|
|
17
17
|
if (this.connection.readyState === 1) {
|
|
18
18
|
this.logger.log('MongoDB connected successfully');
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
// Log thông tin về connection pool
|
|
21
21
|
const poolInfo = this.getConnectionPoolInfo();
|
|
22
22
|
this.logger.log(`MongoDB connection pool initialized: ${JSON.stringify(poolInfo)}`);
|
|
@@ -79,7 +79,7 @@ export class MongodbService implements OnModuleInit {
|
|
|
79
79
|
readyState: this.getReadyStateText(this.connection.readyState),
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
|
-
|
|
82
|
+
|
|
83
83
|
// Cách 2: Nếu không có getClient, sử dụng cách khác
|
|
84
84
|
return {
|
|
85
85
|
readyState: this.getReadyStateText(this.connection.readyState),
|