Avoid iterating clients twice in the api_server loop (#8733)

This commit is contained in:
J. Nick Koston 2025-05-12 17:29:50 -05:00 committed by GitHub
parent 5b2c19bc86
commit f4eb75e4e0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -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_) {
// 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->loop();
client_index++; // Move to next client
}
}
} }
if (this->reboot_timeout_ != 0) { if (this->reboot_timeout_ != 0) {