This commit is contained in:
J. Nick Koston
2026-01-06 08:30:13 -10:00
parent c4d3a56cc9
commit 195b606259
2 changed files with 25 additions and 5 deletions
+12 -3
View File
@@ -1826,9 +1826,18 @@ bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) {
return false;
}
// Toggle NODELAY based on message type:
// - Log messages: Enable Nagle (NODELAY=false) so they coalesce into fewer packets
// - All other messages: Disable Nagle (NODELAY=true) for immediate delivery
// Toggle Nagle's algorithm based on message type to prevent log messages from
// filling the TCP send buffer and crowding out important state updates.
//
// - Log messages: Enable Nagle (NODELAY=false) so small log packets coalesce
// into fewer, larger packets. They flush naturally via TCP delayed ACK timer
// (~200ms), buffer filling, or when a state update triggers a flush.
//
// - All other messages (state updates, responses): Disable Nagle (NODELAY=true)
// for immediate delivery. These are time-sensitive and should not be delayed.
//
// This must be done proactively BEFORE the buffer fills up - checking buffer
// state here would be too late since we'd already be in a degraded state.
this->helper_->set_nodelay(!is_log_message);
APIError err = this->helper_->write_protobuf_packet(message_type, buffer);
+13 -2
View File
@@ -111,7 +111,15 @@ class APIFrameHelper {
}
return APIError::OK;
}
/// Set TCP_NODELAY option. Only calls setsockopt when state changes.
/// Toggle TCP_NODELAY socket option to control Nagle's algorithm.
///
/// This is used to allow log messages to coalesce (Nagle enabled) while keeping
/// state updates low-latency (NODELAY enabled). Without this, many small log
/// packets fill the TCP send buffer, crowding out important state updates.
///
/// State is tracked to minimize setsockopt() overhead - on lwip_raw (ESP8266/RP2040)
/// this is just a boolean assignment; on other platforms it's a lightweight syscall.
///
/// @param enable true to enable NODELAY (disable Nagle), false to enable Nagle
/// @return true if successful or already in desired state
bool set_nodelay(bool enable) {
@@ -211,7 +219,10 @@ class APIFrameHelper {
uint8_t tx_buf_head_{0};
uint8_t tx_buf_tail_{0};
uint8_t tx_buf_count_{0};
bool nodelay_enabled_{true}; // Tracks current TCP_NODELAY state
// Tracks TCP_NODELAY state to minimize setsockopt() calls. Initialized to true
// since init_common_() enables NODELAY. Used by set_nodelay() to allow log
// messages to coalesce while keeping state updates low-latency.
bool nodelay_enabled_{true};
// Common initialization for both plaintext and noise protocols
APIError init_common_();