Skip to content

Commit d83adaa

Browse files
maxholmanclaude
andcommitted
refactor(transport): eliminate latency channel — update registry directly
The Pong handler in the control loop now calls registry.update_latency() directly instead of forwarding RTT measurements through a dedicated mpsc channel. This removes 4 channel pair creations (one per transport impl), the latency_rx field from ConnectResult/AcceptResult, and the latency_rx parameter from spawn_heartbeat. The peer name for registry lookups is extracted from the Handshake message — on the server side at construction, on the client side when the first Handshake arrives through the control stream. QuicClient and WsClient gain a peer_registry field that daemon modes set before calling connect(). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 97b41a1 commit d83adaa

12 files changed

Lines changed: 123 additions & 179 deletions

File tree

crates/core/src/client/client.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ pub struct ConnectResult<T: wallhack_transport::Transport + ?Sized> {
4444
control_tx: mpsc::Sender<ControlMessage>,
4545
/// Receiver for the server's `Handshake` (delivered via the control loop).
4646
peer_handshake_rx: Option<oneshot::Receiver<Handshake>>,
47-
/// Pong-derived latency measurements from the control loop (milliseconds).
48-
latency_rx: Option<mpsc::Receiver<f64>>,
4947
}
5048

5149
impl<T: wallhack_transport::Transport + ?Sized> ConnectResult<T> {
@@ -57,7 +55,6 @@ impl<T: wallhack_transport::Transport + ?Sized> ConnectResult<T> {
5755
tasks: ConnectionTasks,
5856
control_tx: mpsc::Sender<ControlMessage>,
5957
peer_handshake_rx: Option<oneshot::Receiver<Handshake>>,
60-
latency_rx: Option<mpsc::Receiver<f64>>,
6158
) -> Self {
6259
Self {
6360
channels,
@@ -66,7 +63,6 @@ impl<T: wallhack_transport::Transport + ?Sized> ConnectResult<T> {
6663
transport,
6764
control_tx,
6865
peer_handshake_rx,
69-
latency_rx,
7066
}
7167
}
7268

@@ -110,8 +106,6 @@ pub struct ErasedConnectResult {
110106
pub control_tx: mpsc::Sender<ControlMessage>,
111107
pub peer_handshake_rx: Option<oneshot::Receiver<Handshake>>,
112108
pub peer_addr: String,
113-
/// Pong-derived latency measurements from the control loop (milliseconds).
114-
pub latency_rx: Option<mpsc::Receiver<f64>>,
115109
}
116110

117111
impl<T> ConnectResult<T>
@@ -135,7 +129,6 @@ where
135129
channels: self.channels,
136130
tasks: self.tasks,
137131
control_tx: self.control_tx,
138-
latency_rx: self.latency_rx,
139132
}
140133
}
141134
}

crates/core/src/client/quic/mod.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ pub struct QuicClient {
6464
name: Option<String>,
6565
psk: Option<zeroize::Zeroizing<String>>,
6666
local_handshake: Option<Handshake>,
67+
/// Peer registry for direct latency updates in the control loop.
68+
/// Set by the daemon mode before calling `connect()`.
69+
pub peer_registry: Option<std::sync::Arc<crate::control::peers::Registry>>,
6770
}
6871

6972
impl Client for QuicClient {
@@ -101,6 +104,7 @@ impl Client for QuicClient {
101104
name: config.name,
102105
psk: config.psk,
103106
local_handshake: config.local_handshake,
107+
peer_registry: None,
104108
})
105109
}
106110

@@ -170,18 +174,17 @@ impl Client for QuicClient {
170174

171175
// Create oneshot for receiving server's Handshake via the control loop.
172176
let (handshake_tx, handshake_rx) = tokio::sync::oneshot::channel::<Handshake>();
173-
let (latency_tx, latency_rx) = tokio::sync::mpsc::channel::<f64>(4);
174-
175177
// Spawn control stream task
176178
let control_handle = {
177179
let transport = Arc::clone(&transport);
180+
let peer_registry = self.peer_registry.clone();
178181
tokio::spawn(async move {
179182
let mut channels = protocol::ControlChannels {
180183
outgoing_rx: control_rx,
181184
handshake_tx: Some(handshake_tx),
182-
latency_tx: Some(latency_tx),
183185
control_response_tx: None,
184-
peer_registry: None,
186+
peer_registry,
187+
peer_name: None,
185188
};
186189
match protocol::run_control_stream_initiator(
187190
&*transport,
@@ -235,7 +238,6 @@ impl Client for QuicClient {
235238
tasks,
236239
control_tx,
237240
Some(handshake_rx),
238-
Some(latency_rx),
239241
))
240242
}
241243

crates/core/src/client/ws/mod.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,9 @@ impl Default for WsClientConfig {
196196
pub struct WsClient {
197197
config: WsClientConfig,
198198
tls_connector: Option<TlsConnector>,
199+
/// Peer registry for direct latency updates in the control loop.
200+
/// Set by the daemon mode before calling `connect()`.
201+
pub peer_registry: Option<std::sync::Arc<crate::control::peers::Registry>>,
199202
}
200203

201204
impl WsClient {
@@ -223,6 +226,7 @@ impl WsClient {
223226
Ok(Self {
224227
config,
225228
tls_connector,
229+
peer_registry: None,
226230
})
227231
}
228232

@@ -387,18 +391,17 @@ impl WsClient {
387391

388392
// Create oneshot for receiving server's Handshake via the control loop.
389393
let (handshake_tx, handshake_rx) = tokio::sync::oneshot::channel::<Handshake>();
390-
let (latency_tx, latency_rx) = tokio::sync::mpsc::channel::<f64>(4);
391-
392394
// Spawn control stream task
393395
let control_handle = {
394396
let transport = Arc::clone(&transport);
397+
let peer_registry = self.peer_registry.clone();
395398
tokio::spawn(async move {
396399
let mut channels = protocol::ControlChannels {
397400
outgoing_rx: control_rx,
398401
handshake_tx: Some(handshake_tx), // receive server's Handshake
399-
latency_tx: Some(latency_tx),
400402
control_response_tx: None,
401-
peer_registry: None,
403+
peer_registry,
404+
peer_name: None,
402405
};
403406
match protocol::run_control_stream_initiator(
404407
&*transport,
@@ -452,7 +455,6 @@ impl WsClient {
452455
tasks,
453456
control_tx,
454457
Some(handshake_rx),
455-
Some(latency_rx),
456458
))
457459
}
458460
}

crates/core/src/server/quic/mod.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,7 @@ impl Server for QuicServer {
210210
.clone()
211211
.unwrap_or_else(RouteTable::shared);
212212

213-
// Create latency channel so pong-derived RTT measurements are available
214-
// to the caller (e.g. for registry updates and one-shot ping responses).
215-
let (latency_tx, latency_rx) = tokio::sync::mpsc::channel::<f64>(4);
213+
let peer_name = peer_handshake.as_ref().map(|hs| hs.name.clone());
216214
let route_updates = self.options.route_updates.clone().unwrap_or_else(|| {
217215
let (tx, _) = tokio::sync::broadcast::channel(16);
218216
tx
@@ -225,10 +223,10 @@ impl Server for QuicServer {
225223
let handler = Handler::new(handler_config, metrics, peers, routes, route_updates);
226224
let mut channels = protocol::ControlChannels {
227225
outgoing_rx: control_rx,
228-
handshake_tx: None, // Handshake already read above
229-
latency_tx: Some(latency_tx),
226+
handshake_tx: None, // Handshake already read above
230227
control_response_tx: None, // server doesn't issue ControlRequests
231228
peer_registry: Some(peer_registry),
229+
peer_name,
232230
};
233231
let mut control_stream =
234232
wallhack_transport::erased::BoxBiStream::new(control_stream);
@@ -247,7 +245,6 @@ impl Server for QuicServer {
247245
metrics,
248246
peer_handshake,
249247
control_tx,
250-
latency_rx,
251248
channel_binding,
252249
)))
253250
}

crates/core/src/server/server.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,6 @@ pub struct AcceptResult<T: Transport> {
6565
transport: Arc<T>,
6666
/// Channel for injecting messages into the control stream.
6767
control_tx: mpsc::Sender<ControlMessage>,
68-
/// Receiver for pong-derived latency measurements (milliseconds) from the
69-
/// control loop. Used by one-shot ping callers.
70-
latency_rx: Option<mpsc::Receiver<f64>>,
7168
/// TLS channel binding bytes for PSK proof verification.
7269
channel_binding: Option<[u8; crate::psk::CHANNEL_BINDING_LEN]>,
7370
}
@@ -80,7 +77,6 @@ pub struct ErasedAcceptResult {
8077
pub peer_handshake: Option<Handshake>,
8178
pub transport: Arc<dyn ErasedTransport>,
8279
pub control_tx: mpsc::Sender<ControlMessage>,
83-
pub latency_rx: Option<mpsc::Receiver<f64>>,
8480
pub channel_binding: Option<[u8; crate::psk::CHANNEL_BINDING_LEN]>,
8581
}
8682

@@ -100,7 +96,6 @@ where
10096
peer_handshake: self.peer_handshake.take(),
10197
transport: self.transport as Arc<dyn ErasedTransport>,
10298
control_tx: self.control_tx,
103-
latency_rx: self.latency_rx.take(),
10499
channel_binding: self.channel_binding,
105100
}
106101
}
@@ -110,15 +105,13 @@ impl<T: Transport> AcceptResult<T> {
110105
/// Creates a new accept result with an already-received peer `Handshake`
111106
/// and a latency receiver for pong-derived RTT measurements.
112107
#[must_use]
113-
#[allow(clippy::too_many_arguments)] // accept result construction; will be simplified when builder pattern is adopted
114108
pub fn with_handshake(
115109
transport: Arc<T>,
116110
channels: DataChannels,
117111
peer_addr: String,
118112
metrics: SharedMetrics,
119113
peer_handshake: Option<Handshake>,
120114
control_tx: mpsc::Sender<ControlMessage>,
121-
latency_rx: mpsc::Receiver<f64>,
122115
channel_binding: Option<[u8; crate::psk::CHANNEL_BINDING_LEN]>,
123116
) -> Self {
124117
Self {
@@ -128,7 +121,6 @@ impl<T: Transport> AcceptResult<T> {
128121
peer_handshake,
129122
transport,
130123
control_tx,
131-
latency_rx: Some(latency_rx),
132124
channel_binding,
133125
}
134126
}
@@ -178,11 +170,6 @@ impl<T: Transport> AcceptResult<T> {
178170
&self.control_tx
179171
}
180172

181-
/// Takes the latency receiver for pong-derived RTT measurements.
182-
pub fn take_latency_rx(&mut self) -> Option<mpsc::Receiver<f64>> {
183-
self.latency_rx.take()
184-
}
185-
186173
/// Returns the TLS channel binding bytes for this connection.
187174
#[must_use]
188175
pub fn channel_binding(&self) -> Option<&[u8; crate::psk::CHANNEL_BINDING_LEN]> {

crates/core/src/server/ws/mod.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -291,9 +291,7 @@ impl Server for WebSocketServer {
291291
.clone()
292292
.unwrap_or_else(RouteTable::shared);
293293

294-
// Create latency channel so pong-derived RTT measurements are available
295-
// to the caller (e.g. for registry updates and one-shot ping responses).
296-
let (latency_tx, latency_rx) = tokio::sync::mpsc::channel::<f64>(4);
294+
let peer_name = peer_handshake.as_ref().map(|hs| hs.name.clone());
297295
let route_updates = self.options.route_updates.clone().unwrap_or_else(|| {
298296
let (tx, _) = tokio::sync::broadcast::channel(16);
299297
tx
@@ -306,10 +304,10 @@ impl Server for WebSocketServer {
306304
let handler = Handler::new(handler_config, metrics, peers, routes, route_updates);
307305
let mut channels = protocol::ControlChannels {
308306
outgoing_rx: control_rx,
309-
handshake_tx: None, // Handshake already read above
310-
latency_tx: Some(latency_tx),
307+
handshake_tx: None, // Handshake already read above
311308
control_response_tx: None, // server doesn't issue ControlRequests
312309
peer_registry: Some(peer_registry),
310+
peer_name,
313311
};
314312
let mut control_stream =
315313
wallhack_transport::erased::BoxBiStream::new(control_stream);
@@ -328,7 +326,6 @@ impl Server for WebSocketServer {
328326
metrics,
329327
peer_handshake,
330328
control_tx,
331-
latency_rx,
332329
channel_binding,
333330
)))
334331
}

0 commit comments

Comments
 (0)