cabana: introduce `OneShotHttpRequest` to prevent concurrent HTTP requests (#34136)

add OneShotHttpRequest class for single-use HTTP requests
pull/34139/head
Dean Lee 5 months ago committed by GitHub
parent adc347d12b
commit 049f6c1dd5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 32
      tools/cabana/streams/routes.cc
  2. 6
      tools/cabana/streams/routes.h

@ -9,7 +9,19 @@
#include <QMessageBox> #include <QMessageBox>
#include <QPainter> #include <QPainter>
#include "system/hardware/hw.h" class OneShotHttpRequest : public HttpRequest {
public:
OneShotHttpRequest(QObject *parent) : HttpRequest(parent, false) {}
void send(const QString &url) {
if (reply) {
reply->disconnect();
reply->abort();
reply->deleteLater();
reply = nullptr;
}
sendRequest(url);
}
};
// The RouteListWidget class extends QListWidget to display a custom message when empty // The RouteListWidget class extends QListWidget to display a custom message when empty
class RouteListWidget : public QListWidget { class RouteListWidget : public QListWidget {
@ -29,7 +41,7 @@ public:
QString empty_text_ = tr("No items"); QString empty_text_ = tr("No items");
}; };
RoutesDialog::RoutesDialog(QWidget *parent) : QDialog(parent) { RoutesDialog::RoutesDialog(QWidget *parent) : QDialog(parent), route_requester_(new OneShotHttpRequest(this)) {
setWindowTitle(tr("Remote routes")); setWindowTitle(tr("Remote routes"));
QFormLayout *layout = new QFormLayout(this); QFormLayout *layout = new QFormLayout(this);
@ -47,6 +59,7 @@ RoutesDialog::RoutesDialog(QWidget *parent) : QDialog(parent) {
period_selector_->addItem(tr("Last 6 months"), 180); period_selector_->addItem(tr("Last 6 months"), 180);
// Connect signals and slots // Connect signals and slots
QObject::connect(route_requester_, &HttpRequest::requestDone, this, &RoutesDialog::parseRouteList);
connect(device_list_, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &RoutesDialog::fetchRoutes); connect(device_list_, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &RoutesDialog::fetchRoutes);
connect(period_selector_, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &RoutesDialog::fetchRoutes); connect(period_selector_, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &RoutesDialog::fetchRoutes);
connect(route_list_, &QListWidget::itemDoubleClicked, this, &QDialog::accept); connect(route_list_, &QListWidget::itemDoubleClicked, this, &QDialog::accept);
@ -54,7 +67,7 @@ RoutesDialog::RoutesDialog(QWidget *parent) : QDialog(parent) {
QObject::connect(button_box, &QDialogButtonBox::rejected, this, &QDialog::reject); QObject::connect(button_box, &QDialogButtonBox::rejected, this, &QDialog::reject);
// Send request to fetch devices // Send request to fetch devices
HttpRequest *http = new HttpRequest(this, !Hardware::PC()); HttpRequest *http = new HttpRequest(this, false);
QObject::connect(http, &HttpRequest::requestDone, this, &RoutesDialog::parseDeviceList); QObject::connect(http, &HttpRequest::requestDone, this, &RoutesDialog::parseDeviceList);
http->sendRequest(CommaApi::BASE_URL + "/v1/me/devices/"); http->sendRequest(CommaApi::BASE_URL + "/v1/me/devices/");
} }
@ -82,9 +95,6 @@ void RoutesDialog::fetchRoutes() {
route_list_->clear(); route_list_->clear();
route_list_->setEmptyText(tr("Loading...")); route_list_->setEmptyText(tr("Loading..."));
HttpRequest *http = new HttpRequest(this, !Hardware::PC());
QObject::connect(http, &HttpRequest::requestDone, this, &RoutesDialog::parseRouteList);
// Construct URL with selected device and date range // Construct URL with selected device and date range
auto dongle_id = device_list_->currentData().toString(); auto dongle_id = device_list_->currentData().toString();
QDateTime current = QDateTime::currentDateTime(); QDateTime current = QDateTime::currentDateTime();
@ -92,7 +102,7 @@ void RoutesDialog::fetchRoutes() {
.arg(CommaApi::BASE_URL).arg(dongle_id) .arg(CommaApi::BASE_URL).arg(dongle_id)
.arg(current.addDays(-(period_selector_->currentData().toInt())).toMSecsSinceEpoch()) .arg(current.addDays(-(period_selector_->currentData().toInt())).toMSecsSinceEpoch())
.arg(current.toMSecsSinceEpoch()); .arg(current.toMSecsSinceEpoch());
http->sendRequest(url); route_requester_->sendRequest(url);
} }
void RoutesDialog::parseRouteList(const QString &json, bool success, QNetworkReply::NetworkError err) { void RoutesDialog::parseRouteList(const QString &json, bool success, QNetworkReply::NetworkError err) {
@ -115,9 +125,7 @@ void RoutesDialog::parseRouteList(const QString &json, bool success, QNetworkRep
sender()->deleteLater(); sender()->deleteLater();
} }
void RoutesDialog::accept() { QString RoutesDialog::route() {
if (auto current_item = route_list_->currentItem()) { auto current_item = route_list_->currentItem();
route_ = current_item->data(Qt::UserRole).toString(); return current_item ? current_item->data(Qt::UserRole).toString() : "";
}
QDialog::accept();
} }

@ -6,15 +6,15 @@
#include "selfdrive/ui/qt/api.h" #include "selfdrive/ui/qt/api.h"
class RouteListWidget; class RouteListWidget;
class OneShotHttpRequest;
class RoutesDialog : public QDialog { class RoutesDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
RoutesDialog(QWidget *parent); RoutesDialog(QWidget *parent);
QString route() const { return route_; } QString route();
protected: protected:
void accept() override;
void parseDeviceList(const QString &json, bool success, QNetworkReply::NetworkError err); void parseDeviceList(const QString &json, bool success, QNetworkReply::NetworkError err);
void parseRouteList(const QString &json, bool success, QNetworkReply::NetworkError err); void parseRouteList(const QString &json, bool success, QNetworkReply::NetworkError err);
void fetchRoutes(); void fetchRoutes();
@ -22,5 +22,5 @@ protected:
QComboBox *device_list_; QComboBox *device_list_;
QComboBox *period_selector_; QComboBox *period_selector_;
RouteListWidget *route_list_; RouteListWidget *route_list_;
QString route_; OneShotHttpRequest *route_requester_;
}; };

Loading…
Cancel
Save