Skip to content

Commit 74c70c1

Browse files
authored
fix: make the max number of ws-connections configurable (#397)
Introduce new paramater `max-ws-connections` to the [rpc] section of the config, by default this value is set to 16384, but setting it to anything below 200K is also fine, anything above that value will create significant memory pressure by slab preallocation, and can even trigger an OOM kill. <!-- greptile_comment --> ## Greptile Summary Adds configurable WebSocket connection limits to prevent memory exhaustion, with a new `max-ws-connections` parameter in the RPC config defaulting to 16384 connections. - Added `max_ws_connections` field to `magicblock-pubsub/src/pubsub_service.rs` to control concurrent WebSocket connections - Modified `magicblock-config/src/rpc.rs` to expose the new config parameter with default of 16384 - Added validation to keep connections under 200K to prevent slab preallocation memory pressure - Updated config test files to verify proper parsing and defaults - Integrated limit through PubsubConfig initialization in `magicblock-api/src/magic_validator.rs` <!-- /greptile_comment -->
1 parent 190b676 commit 74c70c1

File tree

5 files changed

+25
-3
lines changed

5 files changed

+25
-3
lines changed

magicblock-api/src/magic_validator.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ impl MagicValidator {
325325
let pubsub_config = PubsubConfig::from_rpc(
326326
config.validator_config.rpc.addr,
327327
config.validator_config.rpc.port,
328+
config.validator_config.rpc.max_ws_connections,
328329
);
329330
validator::init_validator_authority(identity_keypair);
330331

magicblock-config/src/rpc.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::net::{IpAddr, Ipv4Addr, SocketAddr};
33
use serde::{Deserialize, Serialize};
44

55
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
6-
#[serde(deny_unknown_fields)]
6+
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
77
pub struct RpcConfig {
88
#[serde(
99
default = "default_addr",
@@ -13,13 +13,16 @@ pub struct RpcConfig {
1313
pub addr: IpAddr,
1414
#[serde(default = "default_port")]
1515
pub port: u16,
16+
#[serde(default = "default_max_ws_connections")]
17+
pub max_ws_connections: usize,
1618
}
1719

1820
impl Default for RpcConfig {
1921
fn default() -> Self {
2022
Self {
2123
addr: default_addr(),
2224
port: default_port(),
25+
max_ws_connections: default_max_ws_connections(),
2326
}
2427
}
2528
}
@@ -57,3 +60,7 @@ fn default_addr() -> IpAddr {
5760
fn default_port() -> u16 {
5861
8899
5962
}
63+
64+
fn default_max_ws_connections() -> usize {
65+
16384
66+
}

magicblock-config/tests/parse_config.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ fn test_local_dev_with_programs_toml() {
9797
}],
9898
rpc: RpcConfig {
9999
addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
100-
port: 7799
100+
port: 7799,
101+
max_ws_connections: 16384
101102
},
102103
validator: ValidatorConfig {
103104
millis_per_slot: 14,

magicblock-config/tests/read_config.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ fn test_load_local_dev_with_programs_toml() {
4545
rpc: RpcConfig {
4646
addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
4747
port: 7799,
48+
max_ws_connections: 16384
4849
},
4950
geyser_grpc: GeyserGrpcConfig {
5051
addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
@@ -128,6 +129,7 @@ fn test_load_local_dev_with_programs_toml_envs_override() {
128129
rpc: RpcConfig {
129130
addr: IpAddr::V4(Ipv4Addr::new(0, 1, 0, 1)),
130131
port: 123,
132+
max_ws_connections: 16384
131133
},
132134
geyser_grpc: GeyserGrpcConfig {
133135
addr: IpAddr::V4(Ipv4Addr::new(0, 1, 0, 1)),

magicblock-pubsub/src/pubsub_service.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,18 @@ use crate::{
2727
#[derive(Clone)]
2828
pub struct PubsubConfig {
2929
socket: SocketAddr,
30+
max_connections: usize,
3031
}
3132

3233
impl PubsubConfig {
33-
pub fn from_rpc(rpc_addr: IpAddr, rpc_port: u16) -> Self {
34+
pub fn from_rpc(
35+
rpc_addr: IpAddr,
36+
rpc_port: u16,
37+
max_connections: usize,
38+
) -> Self {
3439
Self {
3540
socket: SocketAddr::new(rpc_addr, rpc_port + 1),
41+
max_connections,
3642
}
3743
}
3844
}
@@ -41,6 +47,7 @@ impl Default for PubsubConfig {
4147
fn default() -> Self {
4248
Self {
4349
socket: SocketAddr::from(([0, 0, 0, 0], DEFAULT_RPC_PUBSUB_PORT)),
50+
max_connections: 16384,
4451
}
4552
}
4653
}
@@ -89,6 +96,10 @@ impl PubsubService {
8996
|context: &RequestContext| Arc::new(Session::new(context.sender()));
9097

9198
ServerBuilder::with_meta_extractor(self.io, extractor)
99+
// NOTE: we just set the max number of allowed connections to a reasonably high value
100+
// to satisfy most of the use cases, however this number cannot be arbitrarily large
101+
// due to the preallocation involved, and a large value will trigger an OOM Kill
102+
.max_connections(self.config.max_connections)
92103
.start(&self.config.socket)
93104
}
94105

0 commit comments

Comments
 (0)