mirror of
https://github.com/telemt/telemt.git
synced 2026-11-01 13:21:58 +03:00
Carrier negotiation + WebSocket lifecycle
Co-Authored-By: brekotis <93345790+brekotis@users.noreply.github.com>
This commit is contained in:
@@ -339,6 +339,9 @@ const WEB_TIMEOUTS_CONFIG_KEYS: &[&str] = &[
|
||||
"stream_handshake_secs",
|
||||
"stream_first_byte_secs",
|
||||
"long_poll_secs",
|
||||
"bridge_request_secs",
|
||||
"bridge_retry_secs",
|
||||
"carrier_probe_coalesce_ms",
|
||||
"lane_open_wait_secs",
|
||||
"carrier_health_secs",
|
||||
"websocket_upgrade_secs",
|
||||
|
||||
@@ -33,6 +33,18 @@ pub(super) fn validate(timeouts: &WebTimeoutsConfig) -> Result<()> {
|
||||
if !(2..=86_400).contains(&timeouts.carrier_learning_secs) {
|
||||
return config_error("web.timeouts.carrier_learning_secs must be within [2, 86400]");
|
||||
}
|
||||
if !(1..=60).contains(&timeouts.bridge_request_secs) {
|
||||
return config_error("web.timeouts.bridge_request_secs must be within [1, 60]");
|
||||
}
|
||||
if !(1..=300).contains(&timeouts.bridge_retry_secs) {
|
||||
return config_error("web.timeouts.bridge_retry_secs must be within [1, 300]");
|
||||
}
|
||||
if timeouts.bridge_request_secs > timeouts.bridge_retry_secs {
|
||||
return config_error("web.timeouts.bridge_request_secs must not exceed bridge_retry_secs");
|
||||
}
|
||||
if timeouts.carrier_probe_coalesce_ms > 10 {
|
||||
return config_error("web.timeouts.carrier_probe_coalesce_ms must be within [0, 10]");
|
||||
}
|
||||
if timeouts.stream_first_byte_secs > 300 {
|
||||
return config_error("web.timeouts.stream_first_byte_secs must be within [1, 300]");
|
||||
}
|
||||
|
||||
@@ -108,10 +108,10 @@ fn web_carriers_reject_true_empty_and_duplicates() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn web_carrier_deadlines_and_learning_window_are_configurable() {
|
||||
fn web_carrier_and_bridge_deadlines_are_configurable() {
|
||||
let configured = WEB_CONFIG.replace(
|
||||
"[[web.vhosts]]",
|
||||
"[web.timeouts]\ncarrier_negotiation_deadlines_secs = [1, 2, 4, 9]\ncarrier_learning_secs = 30\n\n[[web.vhosts]]",
|
||||
"[web.timeouts]\ncarrier_negotiation_deadlines_secs = [1, 2, 4, 9]\ncarrier_learning_secs = 30\nbridge_request_secs = 7\nbridge_retry_secs = 41\ncarrier_probe_coalesce_ms = 4\n\n[[web.vhosts]]",
|
||||
);
|
||||
let config = load_config_from_temp_toml(&configured);
|
||||
assert_eq!(
|
||||
@@ -119,6 +119,51 @@ fn web_carrier_deadlines_and_learning_window_are_configurable() {
|
||||
[1, 2, 4, 9]
|
||||
);
|
||||
assert_eq!(config.web.timeouts.carrier_learning_secs, 30);
|
||||
assert_eq!(config.web.timeouts.bridge_request_secs, 7);
|
||||
assert_eq!(config.web.timeouts.bridge_retry_secs, 41);
|
||||
assert_eq!(config.web.timeouts.carrier_probe_coalesce_ms, 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn web_bridge_deadlines_are_known_in_strict_mode() {
|
||||
let configured = WEB_CONFIG.replace(
|
||||
"[[web.vhosts]]",
|
||||
"[web.timeouts]\nbridge_request_secs = 7\nbridge_retry_secs = 41\ncarrier_probe_coalesce_ms = 4\n\n[[web.vhosts]]",
|
||||
);
|
||||
let configured = format!("[general]\nconfig_strict = true\n{configured}");
|
||||
let config = load_config_from_temp_toml(&configured);
|
||||
|
||||
assert_eq!(config.web.timeouts.bridge_request_secs, 7);
|
||||
assert_eq!(config.web.timeouts.bridge_retry_secs, 41);
|
||||
assert_eq!(config.web.timeouts.carrier_probe_coalesce_ms, 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn web_bridge_deadlines_are_bounded_and_ordered() {
|
||||
for (field, value) in [
|
||||
("bridge_request_secs", "0"),
|
||||
("bridge_request_secs", "61"),
|
||||
("bridge_retry_secs", "0"),
|
||||
("bridge_retry_secs", "301"),
|
||||
("carrier_probe_coalesce_ms", "11"),
|
||||
] {
|
||||
let invalid = WEB_CONFIG.replace(
|
||||
"[[web.vhosts]]",
|
||||
&format!("[web.timeouts]\n{field} = {value}\n\n[[web.vhosts]]"),
|
||||
);
|
||||
assert!(
|
||||
load_config_error_from_temp_toml(&invalid).contains(&format!("web.timeouts.{field}"))
|
||||
);
|
||||
}
|
||||
|
||||
let reversed = WEB_CONFIG.replace(
|
||||
"[[web.vhosts]]",
|
||||
"[web.timeouts]\nbridge_request_secs = 20\nbridge_retry_secs = 10\n\n[[web.vhosts]]",
|
||||
);
|
||||
assert!(
|
||||
load_config_error_from_temp_toml(&reversed)
|
||||
.contains("bridge_request_secs must not exceed bridge_retry_secs")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -288,6 +288,15 @@ pub struct WebTimeoutsConfig {
|
||||
/// Maximum wait for one empty downlink long poll.
|
||||
#[serde(default = "default_web_long_poll_timeout_secs")]
|
||||
pub long_poll_secs: u64,
|
||||
/// Deadline for one generated-bridge HTTP attempt and response body.
|
||||
#[serde(default = "default_web_bridge_request_secs")]
|
||||
pub bridge_request_secs: u64,
|
||||
/// Absolute generated-bridge budget for one retryable HTTP operation.
|
||||
#[serde(default = "default_web_bridge_retry_secs")]
|
||||
pub bridge_retry_secs: u64,
|
||||
/// Optional delay for coalescing the first OPEN with immediate DATA.
|
||||
#[serde(default = "default_web_carrier_probe_coalesce_ms")]
|
||||
pub carrier_probe_coalesce_ms: u64,
|
||||
/// Grace for a canonical downlink poll that races its lane OPEN.
|
||||
#[serde(default = "default_web_lane_open_wait_secs")]
|
||||
pub lane_open_wait_secs: u64,
|
||||
@@ -340,6 +349,9 @@ impl Default for WebTimeoutsConfig {
|
||||
stream_handshake_secs: default_web_stream_handshake_timeout_secs(),
|
||||
stream_first_byte_secs: default_web_stream_first_byte_secs(),
|
||||
long_poll_secs: default_web_long_poll_timeout_secs(),
|
||||
bridge_request_secs: default_web_bridge_request_secs(),
|
||||
bridge_retry_secs: default_web_bridge_retry_secs(),
|
||||
carrier_probe_coalesce_ms: default_web_carrier_probe_coalesce_ms(),
|
||||
lane_open_wait_secs: default_web_lane_open_wait_secs(),
|
||||
carrier_health_secs: default_web_carrier_health_secs(),
|
||||
websocket_upgrade_secs: default_web_websocket_upgrade_secs(),
|
||||
|
||||
@@ -85,6 +85,9 @@ u64_default!(default_web_body_timeout_secs, 30);
|
||||
u64_default!(default_web_stream_handshake_timeout_secs, 10);
|
||||
u64_default!(default_web_stream_first_byte_secs, 30);
|
||||
u64_default!(default_web_long_poll_timeout_secs, 25);
|
||||
u64_default!(default_web_bridge_request_secs, 10);
|
||||
u64_default!(default_web_bridge_retry_secs, 90);
|
||||
u64_default!(default_web_carrier_probe_coalesce_ms, 0);
|
||||
u64_default!(default_web_lane_open_wait_secs, 2);
|
||||
u64_default!(default_web_carrier_health_secs, 30);
|
||||
u64_default!(default_web_websocket_upgrade_secs, 5);
|
||||
|
||||
Reference in New Issue
Block a user