Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 43e320a36d | |||
| 6ac4b37532 | |||
| f456b0ba4f | |||
| 69530f73aa |
12
changelog.md
12
changelog.md
@@ -1,5 +1,17 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2026-03-15 - 4.5.2 - fix(remoteingress-core)
|
||||||
|
improve stream flow control retries and increase channel buffer capacity
|
||||||
|
|
||||||
|
- increase per-stream mpsc channel capacity from 128 to 256 on both edge and hub paths
|
||||||
|
- only reset accumulated window update bytes after a successful try_send to avoid dropping flow-control credits when the update channel is busy
|
||||||
|
|
||||||
|
## 2026-03-15 - 4.5.1 - fix(protocol)
|
||||||
|
increase per-stream flow control window and channel buffers to improve high-RTT throughput
|
||||||
|
|
||||||
|
- raise the initial stream window from 256 KB to 4 MB to allow more in-flight data per stream
|
||||||
|
- increase edge and hub mpsc channel capacities from 16 to 128 to better absorb throughput under flow control
|
||||||
|
|
||||||
## 2026-03-15 - 4.5.0 - feat(remoteingress-core)
|
## 2026-03-15 - 4.5.0 - feat(remoteingress-core)
|
||||||
add per-stream flow control for edge and hub tunnel data transfer
|
add per-stream flow control for edge and hub tunnel data transfer
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@serve.zone/remoteingress",
|
"name": "@serve.zone/remoteingress",
|
||||||
"version": "4.5.0",
|
"version": "4.5.2",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "Edge ingress tunnel for DcRouter - accepts incoming TCP connections at network edge and tunnels them to DcRouter SmartProxy preserving client IP via PROXY protocol v1.",
|
"description": "Edge ingress tunnel for DcRouter - accepts incoming TCP connections at network edge and tunnels them to DcRouter SmartProxy preserving client IP via PROXY protocol v1.",
|
||||||
"main": "dist_ts/index.js",
|
"main": "dist_ts/index.js",
|
||||||
|
|||||||
@@ -625,7 +625,7 @@ async fn handle_client_connection(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set up channel for data coming back from hub (capacity 16 is sufficient with flow control)
|
// Set up channel for data coming back from hub (capacity 16 is sufficient with flow control)
|
||||||
let (back_tx, mut back_rx) = mpsc::channel::<Vec<u8>>(16);
|
let (back_tx, mut back_rx) = mpsc::channel::<Vec<u8>>(256);
|
||||||
let send_window = Arc::new(AtomicU32::new(INITIAL_STREAM_WINDOW));
|
let send_window = Arc::new(AtomicU32::new(INITIAL_STREAM_WINDOW));
|
||||||
let window_notify = Arc::new(Notify::new());
|
let window_notify = Arc::new(Notify::new());
|
||||||
{
|
{
|
||||||
@@ -657,10 +657,11 @@ async fn handle_client_connection(
|
|||||||
// Track consumption for flow control
|
// Track consumption for flow control
|
||||||
consumed_since_update += len;
|
consumed_since_update += len;
|
||||||
if consumed_since_update >= WINDOW_UPDATE_THRESHOLD {
|
if consumed_since_update >= WINDOW_UPDATE_THRESHOLD {
|
||||||
let increment = consumed_since_update;
|
let frame = encode_window_update(stream_id, FRAME_WINDOW_UPDATE, consumed_since_update);
|
||||||
consumed_since_update = 0;
|
if wu_tx.try_send(frame).is_ok() {
|
||||||
let frame = encode_window_update(stream_id, FRAME_WINDOW_UPDATE, increment);
|
consumed_since_update = 0;
|
||||||
let _ = wu_tx.try_send(frame);
|
}
|
||||||
|
// If try_send fails, keep accumulating — retry on next threshold
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => break,
|
None => break,
|
||||||
|
|||||||
@@ -477,7 +477,7 @@ async fn handle_edge_connection(
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Create channel for data from edge to this stream (capacity 16 is sufficient with flow control)
|
// Create channel for data from edge to this stream (capacity 16 is sufficient with flow control)
|
||||||
let (data_tx, mut data_rx) = mpsc::channel::<Vec<u8>>(16);
|
let (data_tx, mut data_rx) = mpsc::channel::<Vec<u8>>(256);
|
||||||
let send_window = Arc::new(AtomicU32::new(INITIAL_STREAM_WINDOW));
|
let send_window = Arc::new(AtomicU32::new(INITIAL_STREAM_WINDOW));
|
||||||
let window_notify = Arc::new(Notify::new());
|
let window_notify = Arc::new(Notify::new());
|
||||||
{
|
{
|
||||||
@@ -528,10 +528,11 @@ async fn handle_edge_connection(
|
|||||||
// Track consumption for flow control
|
// Track consumption for flow control
|
||||||
consumed_since_update += len;
|
consumed_since_update += len;
|
||||||
if consumed_since_update >= WINDOW_UPDATE_THRESHOLD {
|
if consumed_since_update >= WINDOW_UPDATE_THRESHOLD {
|
||||||
let increment = consumed_since_update;
|
let frame = encode_window_update(stream_id, FRAME_WINDOW_UPDATE_BACK, consumed_since_update);
|
||||||
consumed_since_update = 0;
|
if wub_tx.try_send(frame).is_ok() {
|
||||||
let frame = encode_window_update(stream_id, FRAME_WINDOW_UPDATE_BACK, increment);
|
consumed_since_update = 0;
|
||||||
let _ = wub_tx.try_send(frame);
|
}
|
||||||
|
// If try_send fails, keep accumulating — retry on next threshold
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => break,
|
None => break,
|
||||||
|
|||||||
@@ -19,8 +19,9 @@ pub const FRAME_HEADER_SIZE: usize = 9;
|
|||||||
pub const MAX_PAYLOAD_SIZE: u32 = 16 * 1024 * 1024;
|
pub const MAX_PAYLOAD_SIZE: u32 = 16 * 1024 * 1024;
|
||||||
|
|
||||||
// Per-stream flow control constants
|
// Per-stream flow control constants
|
||||||
/// Initial per-stream window size (256 KB). With 32KB frames, this allows ~8 frames in flight.
|
/// Initial per-stream window size (4 MB). Sized for full throughput at high RTT:
|
||||||
pub const INITIAL_STREAM_WINDOW: u32 = 256 * 1024;
|
/// at 100ms RTT, this sustains ~40 MB/s per stream.
|
||||||
|
pub const INITIAL_STREAM_WINDOW: u32 = 4 * 1024 * 1024;
|
||||||
/// Send WINDOW_UPDATE after consuming this many bytes (half the initial window).
|
/// Send WINDOW_UPDATE after consuming this many bytes (half the initial window).
|
||||||
pub const WINDOW_UPDATE_THRESHOLD: u32 = INITIAL_STREAM_WINDOW / 2;
|
pub const WINDOW_UPDATE_THRESHOLD: u32 = INITIAL_STREAM_WINDOW / 2;
|
||||||
/// Maximum window size to prevent overflow.
|
/// Maximum window size to prevent overflow.
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@serve.zone/remoteingress',
|
name: '@serve.zone/remoteingress',
|
||||||
version: '4.5.0',
|
version: '4.5.2',
|
||||||
description: 'Edge ingress tunnel for DcRouter - accepts incoming TCP connections at network edge and tunnels them to DcRouter SmartProxy preserving client IP via PROXY protocol v1.'
|
description: 'Edge ingress tunnel for DcRouter - accepts incoming TCP connections at network edge and tunnels them to DcRouter SmartProxy preserving client IP via PROXY protocol v1.'
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user