Skip to content

Commit 820466f

Browse files
updates
1 parent de8f7cd commit 820466f

2 files changed

Lines changed: 54 additions & 53 deletions

File tree

src/crons/websocket/connection.handler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export class ConnectionHandler implements OnGatewayDisconnect, OnGatewayConnecti
1515
handleDisconnect(_client: Socket) { }
1616

1717
handleConnection(client: Socket, ..._args: any[]) {
18-
client.setMaxListeners(12);
18+
client.setMaxListeners(16);
1919
}
2020

2121
hasSubscriptionsWithPrefixes(prefixes: string[]): boolean {

src/crons/websocket/websocket.cron.service.ts

Lines changed: 53 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -45,58 +45,6 @@ export class WebsocketCronService {
4545
private readonly apiConfigService: ApiConfigService,
4646
) { }
4747

48-
@Cron('*/1 * * * * *')
49-
handleWebsocketMetrics() {
50-
const connectedClients = this.server.sockets.sockets.size ?? 0;
51-
52-
// Efficient unique-listener counts per topic
53-
const adapter = this.server.sockets.adapter as any;
54-
const sids: Map<string, Set<string>> = adapter?.sids ?? new Map();
55-
56-
const topicPrefixes: Array<{ key: string; prefix?: string; room?: string }> = [
57-
{ key: 'tx', prefix: TransactionsGateway.keyPrefix },
58-
{ key: 'customTx', prefix: TransactionsCustomGateway.keyPrefix },
59-
{ key: 'events', prefix: EventsGateway.keyPrefix },
60-
{ key: 'customEvents', prefix: EventsCustomGateway.keyPrefix },
61-
{ key: 'blocks', prefix: BlocksGateway.keyPrefix },
62-
{ key: 'pool', prefix: PoolGateway.keyPrefix },
63-
{ key: 'stats', room: 'statsRoom' },
64-
];
65-
66-
const topics: Record<string, number> = {};
67-
for (const { key } of topicPrefixes) topics[key] = 0;
68-
69-
// Count unique sockets per prefix-based topic by scanning socket -> rooms map once
70-
if (sids && sids.size > 0) {
71-
for (const [, rooms] of sids) {
72-
// Track whether this socket has been counted for a given topic key
73-
const matched: Record<string, boolean> = {};
74-
75-
for (const roomName of rooms) {
76-
for (const { key, prefix } of topicPrefixes) {
77-
if (!prefix || matched[key]) continue;
78-
if (roomName.startsWith(prefix)) {
79-
topics[key] += 1;
80-
matched[key] = true;
81-
}
82-
}
83-
}
84-
}
85-
}
86-
87-
// Handle exact-room topics (like statsRoom) directly from rooms map
88-
const rooms: Map<string, Set<string>> = adapter?.rooms ?? new Map();
89-
const statsRoomSet = rooms.get('statsRoom');
90-
if (statsRoomSet) {
91-
topics['stats'] = statsRoomSet.size;
92-
}
93-
94-
this.eventEmitter.emit(MetricsEvents.SetWebsocketMetrics, {
95-
connectedClients,
96-
topics,
97-
});
98-
}
99-
10048
@Cron('*/6 * * * * *')
10149
@Lock({ name: 'Push transactions to subscribers', verbose: true })
10250
async handleTransactionsUpdate() {
@@ -165,6 +113,59 @@ export class WebsocketCronService {
165113
);
166114
}
167115

116+
@Cron('*/10 * * * * *')
117+
@Lock({ name: 'Push websocket subscriptions metrics', verbose: true })
118+
handleWebsocketMetrics() {
119+
const connectedClients = this.server.sockets.sockets.size ?? 0;
120+
121+
// Efficient unique-listener counts per topic
122+
const adapter = this.server.sockets.adapter as any;
123+
const sids: Map<string, Set<string>> = adapter?.sids ?? new Map();
124+
125+
const topicPrefixes: Array<{ key: string; prefix?: string; room?: string }> = [
126+
{ key: 'tx', prefix: TransactionsGateway.keyPrefix },
127+
{ key: 'customTx', prefix: TransactionsCustomGateway.keyPrefix },
128+
{ key: 'events', prefix: EventsGateway.keyPrefix },
129+
{ key: 'customEvents', prefix: EventsCustomGateway.keyPrefix },
130+
{ key: 'blocks', prefix: BlocksGateway.keyPrefix },
131+
{ key: 'pool', prefix: PoolGateway.keyPrefix },
132+
{ key: 'stats', room: 'statsRoom' },
133+
];
134+
135+
const topics: Record<string, number> = {};
136+
for (const { key } of topicPrefixes) topics[key] = 0;
137+
138+
// Count unique sockets per prefix-based topic by scanning socket -> rooms map once
139+
if (sids && sids.size > 0) {
140+
for (const [, rooms] of sids) {
141+
// Track whether this socket has been counted for a given topic key
142+
const matched: Record<string, boolean> = {};
143+
144+
for (const roomName of rooms) {
145+
for (const { key, prefix } of topicPrefixes) {
146+
if (!prefix || matched[key]) continue;
147+
if (roomName.startsWith(prefix)) {
148+
topics[key] += 1;
149+
matched[key] = true;
150+
}
151+
}
152+
}
153+
}
154+
}
155+
156+
// Handle exact-room topics (like statsRoom) directly from rooms map
157+
const rooms: Map<string, Set<string>> = adapter?.rooms ?? new Map();
158+
const statsRoomSet = rooms.get('statsRoom');
159+
if (statsRoomSet) {
160+
topics['stats'] = statsRoomSet.size;
161+
}
162+
163+
this.eventEmitter.emit(MetricsEvents.SetWebsocketMetrics, {
164+
connectedClients,
165+
topics,
166+
});
167+
}
168+
168169
private async getLatestRoundOnChainData() {
169170
const rounds = await this.roundService.getRounds(new RoundFilter({ size: 1 }));
170171
return rounds[0];

0 commit comments

Comments
 (0)