Skip to content

Commit 7fa89cc

Browse files
committed
refactor: move GetPreparedConfigWithUsersHandler to users module and update related imports
- Relocated GetPreparedConfigWithUsersHandler from xray-config to users module
1 parent 6d8586d commit 7fa89cc

File tree

14 files changed

+132
-37
lines changed

14 files changed

+132
-37
lines changed

src/common/axios/axios.service.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ export class AxiosService {
8787
const response = await this.axiosInstance.post<StartXrayCommand.Response>(
8888
nodeUrl,
8989
data,
90+
{
91+
timeout: 60_000,
92+
},
9093
);
9194

9295
return {

src/modules/nodes/events/start-all-nodes/start-all-nodes.handler.ts

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import { ICommandResponse } from '@common/types/command-response.type';
88
import { IXrayConfig } from '@common/helpers/xray-config/interfaces';
99
import { AxiosService } from '@common/axios';
1010

11-
import { GetPreparedConfigWithUsersQuery } from '../../../xray-config/queries/get-prepared-config-with-users';
11+
import { GetPreparedConfigWithUsersQuery } from '@modules/users/queries/get-prepared-config-with-users';
12+
1213
import { NodesRepository } from '../../repositories/nodes.repository';
1314
import { StartAllNodesEvent } from './start-all-nodes.event';
1415
import { NodesEntity } from '../../entities/nodes.entity';
@@ -28,30 +29,51 @@ export class StartAllNodesHandler implements IEventHandler<StartAllNodesEvent> {
2829
}
2930
async handle() {
3031
const startTime = Date.now();
32+
3133
try {
3234
const nodes = await this.nodesRepository.findByCriteria({
3335
isDisabled: false,
3436
});
3537

36-
const mapper = async (node: NodesEntity) => {
37-
let config: ICommandResponse<IXrayConfig> | null = null;
38-
39-
config = await this.getConfigForNode({
40-
excludedInbounds: node.excludedInbounds,
38+
for (const node of nodes) {
39+
await this.nodesRepository.update({
40+
uuid: node.uuid,
41+
isConnecting: true,
4142
});
43+
}
44+
45+
const config = await this.getConfigForNode({
46+
excludedInbounds: [],
47+
excludeInboundsFromConfig: false,
48+
});
49+
50+
this.logger.log(`Config for all nodes fetched within: ${Date.now() - startTime}ms`);
51+
52+
if (!config.isOk || !config.response) {
53+
throw new Error('Failed to get config');
54+
}
4255

43-
if (!config.isOk || !config.response) {
44-
return;
56+
const mapper = async (node: NodesEntity) => {
57+
if (!config.response) {
58+
throw new Error('Failed to get config');
4559
}
4660

61+
const excludedNodeInboundsTags = node.excludedInbounds.map(
62+
(inbound) => inbound.tag,
63+
);
64+
65+
const nodeConfig = config.response;
66+
67+
nodeConfig.inbounds = nodeConfig.inbounds.filter(
68+
(inbound) => !excludedNodeInboundsTags.includes(inbound.tag),
69+
);
70+
4771
const response = await this.axios.startXray(
48-
config.response as unknown as Record<string, unknown>,
72+
nodeConfig as unknown as Record<string, unknown>,
4973
node.address,
5074
node.port,
5175
);
5276

53-
config = null;
54-
5577
switch (response.isOk) {
5678
case false:
5779
await this.nodesRepository.update({
@@ -93,7 +115,7 @@ export class StartAllNodesHandler implements IEventHandler<StartAllNodesEvent> {
93115

94116
await pMap(nodes, mapper, { concurrency: this.CONCURRENCY });
95117

96-
this.logger.debug(`Started all nodes in ${Date.now() - startTime}ms`);
118+
this.logger.log(`Started all nodes in ${Date.now() - startTime}ms`);
97119

98120
return;
99121
} catch (error) {

src/modules/nodes/events/start-node/start-node.handler.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import { EVENTS } from '@libs/contracts/constants';
1010

1111
import { NodeEvent } from '@intergration-modules/telegram-bot/events/nodes/interfaces';
1212

13+
import { GetPreparedConfigWithUsersQuery } from '@modules/users/queries/get-prepared-config-with-users';
1314
import { InboundsEntity } from '@modules/inbounds/entities';
1415

15-
import { GetPreparedConfigWithUsersQuery } from '../../../xray-config/queries/get-prepared-config-with-users';
1616
import { NodesRepository } from '../../repositories/nodes.repository';
1717
import { StartNodeEvent } from './start-node.event';
1818

@@ -30,6 +30,35 @@ export class StartNodeHandler implements IEventHandler<StartNodeEvent> {
3030
try {
3131
const nodeEntity = event.node;
3232

33+
if (nodeEntity.isConnecting) {
34+
return;
35+
}
36+
37+
await this.nodesRepository.update({
38+
uuid: nodeEntity.uuid,
39+
isConnecting: true,
40+
});
41+
42+
const xrayStatusResponse = await this.axios.getXrayStatus(
43+
nodeEntity.address,
44+
nodeEntity.port,
45+
);
46+
47+
if (!xrayStatusResponse.isOk && !xrayStatusResponse.response) {
48+
await this.nodesRepository.update({
49+
uuid: nodeEntity.uuid,
50+
isXrayRunning: false,
51+
isNodeOnline: false,
52+
lastStatusMessage: xrayStatusResponse.message ?? null,
53+
lastStatusChange: new Date(),
54+
isConnected: false,
55+
isConnecting: false,
56+
usersOnline: 0,
57+
});
58+
59+
return;
60+
}
61+
3362
const startTime = Date.now();
3463
const config = await this.getConfigForNode(nodeEntity.excludedInbounds);
3564

@@ -58,7 +87,6 @@ export class StartNodeHandler implements IEventHandler<StartNodeEvent> {
5887
lastStatusChange: new Date(),
5988
isConnected: false,
6089
isConnecting: false,
61-
isDisabled: false,
6290
usersOnline: 0,
6391
});
6492
return;
@@ -74,7 +102,6 @@ export class StartNodeHandler implements IEventHandler<StartNodeEvent> {
74102
isConnected: nodeResponse.isStarted,
75103
lastStatusMessage: nodeResponse.error ?? null,
76104
lastStatusChange: new Date(),
77-
isDisabled: false,
78105
isConnecting: false,
79106
cpuCount: nodeResponse.systemInformation?.cpuCores ?? null,
80107
cpuModel: nodeResponse.systemInformation?.cpuModel ?? null,
Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import { IQueryHandler, QueryHandler } from '@nestjs/cqrs';
1+
import { IQueryHandler, QueryBus, QueryHandler } from '@nestjs/cqrs';
22
import { Logger } from '@nestjs/common';
33

44
import { XRayConfig } from '@common/helpers/xray-config/xray-config.validator';
55
import { ICommandResponse } from '@common/types/command-response.type';
66
import { IXrayConfig } from '@common/helpers/xray-config/interfaces';
77
import { ERRORS } from '@libs/contracts/constants';
88

9-
import { XrayConfigRepository } from '@modules/xray-config/repositories/xray-config.repository';
9+
import { XrayConfigEntity } from '@modules/xray-config/entities/xray-config.entity';
10+
import { GetXrayConfigQuery } from '@modules/xray-config/queries/get-xray-config';
1011
import { UsersRepository } from '@modules/users/repositories/users.repository';
1112

1213
import { GetPreparedConfigWithUsersQuery } from './get-prepared-config-with-users.query';
@@ -18,22 +19,21 @@ export class GetPreparedConfigWithUsersHandler
1819
private readonly logger = new Logger(GetPreparedConfigWithUsersHandler.name);
1920
constructor(
2021
private readonly usersRepository: UsersRepository,
21-
private readonly xrayConfigRepository: XrayConfigRepository,
22+
private readonly queryBus: QueryBus,
2223
) {}
2324

2425
async execute(query: GetPreparedConfigWithUsersQuery): Promise<ICommandResponse<IXrayConfig>> {
2526
let config: XRayConfig | null = null;
2627
try {
27-
const { excludedInbounds } = query;
28+
const { excludedInbounds, excludeInboundsFromConfig } = query;
2829

29-
const dbConfig = await this.xrayConfigRepository.findFirst();
30+
const xrayConfig = await this.getXrayConfig();
3031

31-
if (!dbConfig || !dbConfig.config) {
32-
throw new Error('No XTLS config found in DB!');
33-
}
32+
config = new XRayConfig(xrayConfig.config!);
3433

35-
config = new XRayConfig(dbConfig.config);
36-
config.excludeInbounds(excludedInbounds.map((inbound) => inbound.tag));
34+
if (excludeInboundsFromConfig) {
35+
config.excludeInbounds(excludedInbounds.map((inbound) => inbound.tag));
36+
}
3737

3838
config.processCertificates();
3939

@@ -57,4 +57,10 @@ export class GetPreparedConfigWithUsersHandler
5757
config = null;
5858
}
5959
}
60+
61+
private async getXrayConfig(): Promise<XrayConfigEntity> {
62+
return this.queryBus.execute<GetXrayConfigQuery, XrayConfigEntity>(
63+
new GetXrayConfigQuery(),
64+
);
65+
}
6066
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { InboundsEntity } from '@modules/inbounds/entities';
2+
3+
export class GetPreparedConfigWithUsersQuery {
4+
constructor(
5+
public readonly excludedInbounds: InboundsEntity[],
6+
public readonly excludeInboundsFromConfig: boolean = true,
7+
) {}
8+
}

src/modules/users/queries/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { GetUsersByTrafficStrategyAndStatusHandler } from './get-users-by-traffic-strategy-and-status';
22
import { GetExceededTrafficUsageUsersHandler } from './get-exceeded-traffic-usage-users';
3+
import { GetPreparedConfigWithUsersHandler } from './get-prepared-config-with-users';
34
import { GetUsersForConfigBatchHandler } from './get-users-for-config-batch';
45
import { GetUserByShortUuidHandler } from './get-user-by-short-uuid';
56
import { GetUsersForConfigHandler } from './get-users-for-config';
@@ -22,4 +23,5 @@ export const QUERIES = [
2223
GetUsersByTrafficStrategyAndStatusHandler,
2324
GetUserByUuidHandler,
2425
GetUsersForConfigBatchHandler,
26+
GetPreparedConfigWithUsersHandler,
2527
];

src/modules/users/users.module.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ import { QUERIES } from './queries';
1111
imports: [CqrsModule],
1212
controllers: [UsersController],
1313
providers: [UsersRepository, UserConverter, UsersService, ...QUERIES, ...COMMANDS],
14-
exports: [UsersRepository],
14+
exports: [],
1515
})
1616
export class UsersModule {}

src/modules/xray-config/queries/get-prepared-config-with-users/get-prepared-config-with-users.query.ts

Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { IQueryHandler, QueryHandler } from '@nestjs/cqrs';
2+
import { Logger } from '@nestjs/common';
3+
4+
import { XrayConfigEntity } from '@modules/xray-config/entities/xray-config.entity';
5+
6+
import { XrayConfigRepository } from '../../repositories/xray-config.repository';
7+
import { GetXrayConfigQuery } from './get-xray-config.query';
8+
9+
@QueryHandler(GetXrayConfigQuery)
10+
export class GetXrayConfigHandler implements IQueryHandler<GetXrayConfigQuery, XrayConfigEntity> {
11+
private readonly logger = new Logger(GetXrayConfigHandler.name);
12+
13+
constructor(private readonly xrayConfigRepository: XrayConfigRepository) {}
14+
15+
async execute(): Promise<XrayConfigEntity> {
16+
try {
17+
const config = await this.xrayConfigRepository.findFirst();
18+
19+
if (!config || !config.config) {
20+
throw new Error('No XTLS config found in DB!');
21+
}
22+
23+
return config;
24+
} catch (error) {
25+
this.logger.error(error);
26+
throw error;
27+
}
28+
}
29+
}

0 commit comments

Comments
 (0)