1
0
mirror of https://github.com/esphome/esphome.git synced 2026-02-08 00:31:58 +00:00

[api] Coalesce log packets to reduce buffer pressure and prevent dropped state updates

This commit is contained in:
J. Nick Koston
2026-01-06 08:13:35 -10:00
parent ac42102320
commit c4d3a56cc9
2 changed files with 22 additions and 2 deletions

View File

@@ -1820,10 +1820,17 @@ bool APIConnection::try_to_clear_buffer(bool log_out_of_space) {
return false;
}
bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) {
if (!this->try_to_clear_buffer(message_type != SubscribeLogsResponse::MESSAGE_TYPE)) { // SubscribeLogsResponse
const bool is_log_message = (message_type == SubscribeLogsResponse::MESSAGE_TYPE);
if (!this->try_to_clear_buffer(!is_log_message)) {
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
this->helper_->set_nodelay(!is_log_message);
APIError err = this->helper_->write_protobuf_packet(message_type, buffer);
if (err == APIError::WOULD_BLOCK)
return false;

View File

@@ -111,6 +111,19 @@ class APIFrameHelper {
}
return APIError::OK;
}
/// Set TCP_NODELAY option. Only calls setsockopt when state changes.
/// @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) {
if (this->nodelay_enabled_ == enable)
return true;
int val = enable ? 1 : 0;
int err = this->socket_->setsockopt(IPPROTO_TCP, TCP_NODELAY, &val, sizeof(int));
if (err == 0) {
this->nodelay_enabled_ = enable;
}
return err == 0;
}
virtual APIError write_protobuf_packet(uint8_t type, ProtoWriteBuffer buffer) = 0;
// Write multiple protobuf messages in a single operation
// messages contains (message_type, offset, length) for each message in the buffer
@@ -198,7 +211,7 @@ class APIFrameHelper {
uint8_t tx_buf_head_{0};
uint8_t tx_buf_tail_{0};
uint8_t tx_buf_count_{0};
// 8 bytes total, 0 bytes padding
bool nodelay_enabled_{true}; // Tracks current TCP_NODELAY state
// Common initialization for both plaintext and noise protocols
APIError init_common_();