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:
@@ -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;
|
||||
|
||||
@@ -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_();
|
||||
|
||||
Reference in New Issue
Block a user