mirror of
https://github.com/esphome/esphome.git
synced 2025-07-29 06:36:45 +00:00
Fix web_server busy loop with ungracefully disconnected clients (#9312)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
parent
adb7ccdbc7
commit
d686257cff
@ -125,7 +125,16 @@ void DeferredUpdateEventSource::process_deferred_queue_() {
|
|||||||
if (this->send(message.c_str(), "state") != DISCARDED) {
|
if (this->send(message.c_str(), "state") != DISCARDED) {
|
||||||
// O(n) but memory efficiency is more important than speed here which is why std::vector was chosen
|
// O(n) but memory efficiency is more important than speed here which is why std::vector was chosen
|
||||||
deferred_queue_.erase(deferred_queue_.begin());
|
deferred_queue_.erase(deferred_queue_.begin());
|
||||||
|
this->consecutive_send_failures_ = 0; // Reset failure count on successful send
|
||||||
} else {
|
} else {
|
||||||
|
this->consecutive_send_failures_++;
|
||||||
|
if (this->consecutive_send_failures_ >= MAX_CONSECUTIVE_SEND_FAILURES) {
|
||||||
|
// Too many failures, connection is likely dead
|
||||||
|
ESP_LOGW(TAG, "Closing stuck EventSource connection after %" PRIu16 " failed sends",
|
||||||
|
this->consecutive_send_failures_);
|
||||||
|
this->close();
|
||||||
|
this->deferred_queue_.clear();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,6 +173,8 @@ void DeferredUpdateEventSource::deferrable_send_state(void *source, const char *
|
|||||||
std::string message = message_generator(web_server_, source);
|
std::string message = message_generator(web_server_, source);
|
||||||
if (this->send(message.c_str(), "state") == DISCARDED) {
|
if (this->send(message.c_str(), "state") == DISCARDED) {
|
||||||
deq_push_back_with_dedup_(source, message_generator);
|
deq_push_back_with_dedup_(source, message_generator);
|
||||||
|
} else {
|
||||||
|
this->consecutive_send_failures_ = 0; // Reset failure count on successful send
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,6 +127,8 @@ class DeferredUpdateEventSource : public AsyncEventSource {
|
|||||||
// footprint is more important than speed here)
|
// footprint is more important than speed here)
|
||||||
std::vector<DeferredEvent> deferred_queue_;
|
std::vector<DeferredEvent> deferred_queue_;
|
||||||
WebServer *web_server_;
|
WebServer *web_server_;
|
||||||
|
uint16_t consecutive_send_failures_{0};
|
||||||
|
static constexpr uint16_t MAX_CONSECUTIVE_SEND_FAILURES = 2500; // ~20 seconds at 125Hz loop rate
|
||||||
|
|
||||||
// helper for allowing only unique entries in the queue
|
// helper for allowing only unique entries in the queue
|
||||||
void deq_push_back_with_dedup_(void *source, message_generator_t *message_generator);
|
void deq_push_back_with_dedup_(void *source, message_generator_t *message_generator);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user