mirror of
https://github.com/esphome/esphome.git
synced 2025-06-15 14:56:59 +02:00
Improve shutdown reliability when tx buffer is full (#9043)
This commit is contained in:
parent
3411e45a0a
commit
e8aa7cff36
@ -1886,6 +1886,12 @@ uint16_t APIConnection::try_send_list_info_done(EntityBase *entity, APIConnectio
|
|||||||
return encode_message_to_buffer(resp, ListEntitiesDoneResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
return encode_message_to_buffer(resp, ListEntitiesDoneResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t APIConnection::try_send_disconnect_request(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single) {
|
||||||
|
DisconnectRequest req;
|
||||||
|
return encode_message_to_buffer(req, DisconnectRequest::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t APIConnection::get_estimated_message_size(uint16_t message_type) {
|
uint16_t APIConnection::get_estimated_message_size(uint16_t message_type) {
|
||||||
// Use generated ESTIMATED_SIZE constants from each message type
|
// Use generated ESTIMATED_SIZE constants from each message type
|
||||||
switch (message_type) {
|
switch (message_type) {
|
||||||
@ -2021,6 +2027,8 @@ uint16_t APIConnection::get_estimated_message_size(uint16_t message_type) {
|
|||||||
return ListEntitiesServicesResponse::ESTIMATED_SIZE;
|
return ListEntitiesServicesResponse::ESTIMATED_SIZE;
|
||||||
case ListEntitiesDoneResponse::MESSAGE_TYPE:
|
case ListEntitiesDoneResponse::MESSAGE_TYPE:
|
||||||
return ListEntitiesDoneResponse::ESTIMATED_SIZE;
|
return ListEntitiesDoneResponse::ESTIMATED_SIZE;
|
||||||
|
case DisconnectRequest::MESSAGE_TYPE:
|
||||||
|
return DisconnectRequest::ESTIMATED_SIZE;
|
||||||
default:
|
default:
|
||||||
// Fallback for unknown message types
|
// Fallback for unknown message types
|
||||||
return 24;
|
return 24;
|
||||||
|
@ -426,6 +426,10 @@ class APIConnection : public APIServerConnection {
|
|||||||
static uint16_t try_send_list_info_done(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
static uint16_t try_send_list_info_done(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
bool is_single);
|
bool is_single);
|
||||||
|
|
||||||
|
// Method for DisconnectRequest batching
|
||||||
|
static uint16_t try_send_disconnect_request(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
||||||
|
bool is_single);
|
||||||
|
|
||||||
// Helper function to get estimated message size for buffer pre-allocation
|
// Helper function to get estimated message size for buffer pre-allocation
|
||||||
static uint16_t get_estimated_message_size(uint16_t message_type);
|
static uint16_t get_estimated_message_size(uint16_t message_type);
|
||||||
|
|
||||||
|
@ -496,11 +496,15 @@ void APIServer::on_shutdown() {
|
|||||||
this->socket_ = nullptr;
|
this->socket_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Change batch delay to 5ms for quick flushing during shutdown
|
||||||
|
this->batch_delay_ = 5;
|
||||||
|
|
||||||
// Send disconnect requests to all connected clients
|
// Send disconnect requests to all connected clients
|
||||||
for (auto &c : this->clients_) {
|
for (auto &c : this->clients_) {
|
||||||
if (!c->send_message(DisconnectRequest())) {
|
if (!c->send_message(DisconnectRequest())) {
|
||||||
// If we can't send the disconnect request, mark for immediate closure
|
// If we can't send the disconnect request directly (tx_buffer full),
|
||||||
c->next_close_ = true;
|
// schedule it in the batch so it will be sent with the 5ms timer
|
||||||
|
c->schedule_message_(nullptr, &APIConnection::try_send_disconnect_request, DisconnectRequest::MESSAGE_TYPE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user