mirror of
https://github.com/esphome/esphome.git
synced 2025-07-29 06:36:45 +00:00
Avoid iterating clients twice in the api_server loop (#8733)
This commit is contained in:
parent
5b2c19bc86
commit
f4eb75e4e0
@ -126,19 +126,29 @@ void APIServer::loop() {
|
|||||||
conn->start();
|
conn->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Partition clients into remove and active
|
// Process clients and remove disconnected ones in a single pass
|
||||||
auto new_end = std::partition(this->clients_.begin(), this->clients_.end(),
|
if (!this->clients_.empty()) {
|
||||||
[](const std::unique_ptr<APIConnection> &conn) { return !conn->remove_; });
|
size_t client_index = 0;
|
||||||
// print disconnection messages
|
while (client_index < this->clients_.size()) {
|
||||||
for (auto it = new_end; it != this->clients_.end(); ++it) {
|
auto &client = this->clients_[client_index];
|
||||||
this->client_disconnected_trigger_->trigger((*it)->client_info_, (*it)->client_peername_);
|
|
||||||
ESP_LOGV(TAG, "Removing connection to %s", (*it)->client_info_.c_str());
|
|
||||||
}
|
|
||||||
// resize vector
|
|
||||||
this->clients_.erase(new_end, this->clients_.end());
|
|
||||||
|
|
||||||
for (auto &client : this->clients_) {
|
if (client->remove_) {
|
||||||
client->loop();
|
// Handle disconnection
|
||||||
|
this->client_disconnected_trigger_->trigger(client->client_info_, client->client_peername_);
|
||||||
|
ESP_LOGV(TAG, "Removing connection to %s", client->client_info_.c_str());
|
||||||
|
|
||||||
|
// Swap with the last element and pop (avoids expensive vector shifts)
|
||||||
|
if (client_index < this->clients_.size() - 1) {
|
||||||
|
std::swap(this->clients_[client_index], this->clients_.back());
|
||||||
|
}
|
||||||
|
this->clients_.pop_back();
|
||||||
|
// Don't increment client_index since we need to process the swapped element
|
||||||
|
} else {
|
||||||
|
// Process active client
|
||||||
|
client->loop();
|
||||||
|
client_index++; // Move to next client
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->reboot_timeout_ != 0) {
|
if (this->reboot_timeout_ != 0) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user