Skip to content

Commit a864ae9

Browse files
authored
Add API timeout handling (#3078)
1 parent 314f18a commit a864ae9

12 files changed

Lines changed: 147 additions & 38 deletions

File tree

modules/openapi-generator/src/main/resources/cpp-qt5-client/HttpRequest.cpp.mustache

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,29 @@ void {{prefix}}HttpRequestInput::add_file(QString variable_name, QString local_f
4545
: QObject(parent), manager(nullptr)
4646
{
4747
qsrand(QDateTime::currentDateTime().toTime_t());
48-
48+
timeout = 0;
49+
timer = new QTimer();
4950
manager = new QNetworkAccessManager(this);
5051
connect(manager, &QNetworkAccessManager::finished, this, &{{prefix}}HttpRequestWorker::on_manager_finished);
5152
}
5253

5354
{{prefix}}HttpRequestWorker::~{{prefix}}HttpRequestWorker() {
55+
if(timer != nullptr){
56+
if(timer->isActive()){
57+
timer->stop();
58+
}
59+
timer->deleteLater();
60+
}
5461
}
5562

5663
QMap<QByteArray, QByteArray> {{prefix}}HttpRequestWorker::getResponseHeaders() const {
5764
return headers;
5865
}
5966

67+
void {{prefix}}HttpRequestWorker::setTimeOut(int tout){
68+
timeout = tout;
69+
}
70+
6071
QString {{prefix}}HttpRequestWorker::http_attribute_encode(QString attribute_name, QString input) {
6172
// result structure follows RFC 5987
6273
bool need_utf_encoding = false;
@@ -108,7 +119,7 @@ QString {{prefix}}HttpRequestWorker::http_attribute_encode(QString attribute_nam
108119
void {{prefix}}HttpRequestWorker::execute({{prefix}}HttpRequestInput *input) {
109120
110121
// reset variables
111-
122+
QNetworkReply* reply = nullptr;
112123
QByteArray request_content = "";
113124
response = "";
114125
error_type = QNetworkReply::NoError;
@@ -276,19 +287,19 @@ void {{prefix}}HttpRequestWorker::execute({{prefix}}HttpRequestInput *input) {
276287
}
277288

278289
if (input->http_method == "GET") {
279-
manager->get(request);
290+
reply = manager->get(request);
280291
}
281292
else if (input->http_method == "POST") {
282-
manager->post(request, request_content);
293+
reply = manager->post(request, request_content);
283294
}
284295
else if (input->http_method == "PUT") {
285-
manager->put(request, request_content);
296+
reply = manager->put(request, request_content);
286297
}
287298
else if (input->http_method == "HEAD") {
288-
manager->head(request);
299+
reply = manager->head(request);
289300
}
290301
else if (input->http_method == "DELETE") {
291-
manager->deleteResource(request);
302+
reply = manager->deleteResource(request);
292303
}
293304
else {
294305
#if (QT_VERSION >= 0x050800)
@@ -298,11 +309,16 @@ void {{prefix}}HttpRequestWorker::execute({{prefix}}HttpRequestInput *input) {
298309
buffer->setData(request_content);
299310
buffer->open(QIODevice::ReadOnly);
300311
301-
QNetworkReply* reply = manager->sendCustomRequest(request, input->http_method.toLatin1(), buffer);
312+
reply = manager->sendCustomRequest(request, input->http_method.toLatin1(), buffer);
302313
buffer->setParent(reply);
303314
#endif
304315
}
305-
316+
if(timeout > 0){
317+
timer->setSingleShot(true);
318+
timer->setInterval(timeout);
319+
connect(timer, &QTimer::timeout, this, [=](){ on_manager_timeout(reply); });
320+
timer->start();
321+
}
306322
}
307323

308324
void {{prefix}}HttpRequestWorker::on_manager_finished(QNetworkReply *reply) {
@@ -318,6 +334,16 @@ void {{prefix}}HttpRequestWorker::on_manager_finished(QNetworkReply *reply) {
318334

319335
emit on_execution_finished(this);
320336
}
337+
void {{prefix}}HttpRequestWorker::on_manager_timeout(QNetworkReply *reply) {
338+
error_type = QNetworkReply::TimeoutError;
339+
response = "";
340+
error_str = "Timed out waiting for response";
341+
disconnect(manager, nullptr, nullptr, nullptr);
342+
reply->abort();
343+
reply->deleteLater();
344+
345+
emit on_execution_finished(this);
346+
}
321347
QSslConfiguration* {{prefix}}HttpRequestWorker::sslDefaultConfiguration;
322348

323349

modules/openapi-generator/src/main/resources/cpp-qt5-client/HttpRequest.h.mustache

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <QObject>
1212
#include <QString>
13+
#include <QTimer>
1314
#include <QMap>
1415
#include <QNetworkAccessManager>
1516
#include <QNetworkReply>
@@ -60,24 +61,25 @@ public:
6061
QByteArray response;
6162
QNetworkReply::NetworkError error_type;
6263
QString error_str;
63-
64+
QTimer *timer;
6465
explicit {{prefix}}HttpRequestWorker(QObject *parent = nullptr);
6566
virtual ~{{prefix}}HttpRequestWorker();
6667

6768
QMap<QByteArray, QByteArray> getResponseHeaders() const;
6869
QString http_attribute_encode(QString attribute_name, QString input);
6970
void execute({{prefix}}HttpRequestInput *input);
7071
static QSslConfiguration* sslDefaultConfiguration;
71-
72+
void setTimeOut(int tout);
7273
signals:
7374
void on_execution_finished({{prefix}}HttpRequestWorker *worker);
7475

7576
private:
7677
QNetworkAccessManager *manager;
7778
QMap<QByteArray, QByteArray> headers;
79+
int timeout;
80+
void on_manager_timeout(QNetworkReply *reply);
7881
private slots:
79-
void on_manager_finished(QNetworkReply *reply);
80-
82+
void on_manager_finished(QNetworkReply *reply);
8183
};
8284

8385
{{#cppNamespaceDeclarations}}

modules/openapi-generator/src/main/resources/cpp-qt5-client/api-body.mustache

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,19 @@ namespace {{this}} {
1010
{{/cppNamespaceDeclarations}}
1111

1212
{{classname}}::{{classname}}() : basePath("{{{basePathWithoutHost}}}"),
13-
host("{{#serverHost}}{{#scheme}}{{scheme}}://{{/scheme}}{{serverHost}}{{#serverPort}}:{{serverPort}}{{/serverPort}}{{/serverHost}}") {
13+
host("{{#serverHost}}{{#scheme}}{{scheme}}://{{/scheme}}{{serverHost}}{{#serverPort}}:{{serverPort}}{{/serverPort}}{{/serverHost}}"),
14+
timeout(0){
1415
1516
}
1617

1718
{{classname}}::~{{classname}}() {
1819
1920
}
2021

21-
{{classname}}::{{classname}}(const QString& host, const QString& basePath) {
22+
{{classname}}::{{classname}}(const QString& host, const QString& basePath, const int tout) {
2223
this->host = host;
2324
this->basePath = basePath;
25+
this->timeout = tout;
2426
}
2527

2628
void {{classname}}::setBasePath(const QString& basePath){
@@ -31,6 +33,10 @@ void {{classname}}::setHost(const QString& host){
3133
this->host = host;
3234
}
3335

36+
void {{classname}}::setApiTimeOutMs(const int tout){
37+
timeout = tout;
38+
}
39+
3440
void {{classname}}::addHeaders(const QString& key, const QString& value){
3541
defaultHeaders.insert(key, value);
3642
}
@@ -97,6 +103,7 @@ void
97103
}
98104
{{/collectionFormat}}{{/queryParams}}
99105
{{prefix}}HttpRequestWorker *worker = new {{prefix}}HttpRequestWorker();
106+
worker->setTimeOut(timeout);
100107
{{prefix}}HttpRequestInput input(fullPath, "{{httpMethod}}");
101108
{{#formParams}}
102109
if ({{paramName}} != nullptr) {

modules/openapi-generator/src/main/resources/cpp-qt5-client/api-header.mustache

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,20 @@ class {{classname}}: public QObject {
1818
1919
public:
2020
{{classname}}();
21-
{{classname}}(const QString& host, const QString& basePath);
21+
{{classname}}(const QString& host, const QString& basePath, const int toutMs = 0);
2222
~{{classname}}();
2323

2424
void setBasePath(const QString& basePath);
2525
void setHost(const QString& host);
26+
void setApiTimeOutMs(const int tout);
2627
void addHeaders(const QString& key, const QString& value);
2728

2829
{{#operations}}{{#operation}}void {{nickname}}({{#allParams}}const {{{dataType}}}& {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
2930
{{/operation}}{{/operations}}
3031
private:
3132
QString basePath;
3233
QString host;
34+
int timeout;
3335
QMap<QString, QString> defaultHeaders;
3436
{{#operations}}{{#operation}}void {{nickname}}Callback ({{prefix}}HttpRequestWorker * worker);
3537
{{/operation}}{{/operations}}

samples/client/petstore/cpp-qt5/client/OAIHttpRequest.cpp

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,29 @@ OAIHttpRequestWorker::OAIHttpRequestWorker(QObject *parent)
5454
: QObject(parent), manager(nullptr)
5555
{
5656
qsrand(QDateTime::currentDateTime().toTime_t());
57-
57+
timeout = 0;
58+
timer = new QTimer();
5859
manager = new QNetworkAccessManager(this);
5960
connect(manager, &QNetworkAccessManager::finished, this, &OAIHttpRequestWorker::on_manager_finished);
6061
}
6162

6263
OAIHttpRequestWorker::~OAIHttpRequestWorker() {
64+
if(timer != nullptr){
65+
if(timer->isActive()){
66+
timer->stop();
67+
}
68+
timer->deleteLater();
69+
}
6370
}
6471

6572
QMap<QByteArray, QByteArray> OAIHttpRequestWorker::getResponseHeaders() const {
6673
return headers;
6774
}
6875

76+
void OAIHttpRequestWorker::setTimeOut(int tout){
77+
timeout = tout;
78+
}
79+
6980
QString OAIHttpRequestWorker::http_attribute_encode(QString attribute_name, QString input) {
7081
// result structure follows RFC 5987
7182
bool need_utf_encoding = false;
@@ -117,7 +128,7 @@ QString OAIHttpRequestWorker::http_attribute_encode(QString attribute_name, QStr
117128
void OAIHttpRequestWorker::execute(OAIHttpRequestInput *input) {
118129

119130
// reset variables
120-
131+
QNetworkReply* reply = nullptr;
121132
QByteArray request_content = "";
122133
response = "";
123134
error_type = QNetworkReply::NoError;
@@ -285,19 +296,19 @@ void OAIHttpRequestWorker::execute(OAIHttpRequestInput *input) {
285296
}
286297

287298
if (input->http_method == "GET") {
288-
manager->get(request);
299+
reply = manager->get(request);
289300
}
290301
else if (input->http_method == "POST") {
291-
manager->post(request, request_content);
302+
reply = manager->post(request, request_content);
292303
}
293304
else if (input->http_method == "PUT") {
294-
manager->put(request, request_content);
305+
reply = manager->put(request, request_content);
295306
}
296307
else if (input->http_method == "HEAD") {
297-
manager->head(request);
308+
reply = manager->head(request);
298309
}
299310
else if (input->http_method == "DELETE") {
300-
manager->deleteResource(request);
311+
reply = manager->deleteResource(request);
301312
}
302313
else {
303314
#if (QT_VERSION >= 0x050800)
@@ -307,11 +318,16 @@ void OAIHttpRequestWorker::execute(OAIHttpRequestInput *input) {
307318
buffer->setData(request_content);
308319
buffer->open(QIODevice::ReadOnly);
309320

310-
QNetworkReply* reply = manager->sendCustomRequest(request, input->http_method.toLatin1(), buffer);
321+
reply = manager->sendCustomRequest(request, input->http_method.toLatin1(), buffer);
311322
buffer->setParent(reply);
312323
#endif
313324
}
314-
325+
if(timeout > 0){
326+
timer->setSingleShot(true);
327+
timer->setInterval(timeout);
328+
connect(timer, &QTimer::timeout, this, [=](){ on_manager_timeout(reply); });
329+
timer->start();
330+
}
315331
}
316332

317333
void OAIHttpRequestWorker::on_manager_finished(QNetworkReply *reply) {
@@ -327,6 +343,16 @@ void OAIHttpRequestWorker::on_manager_finished(QNetworkReply *reply) {
327343

328344
emit on_execution_finished(this);
329345
}
346+
void OAIHttpRequestWorker::on_manager_timeout(QNetworkReply *reply) {
347+
error_type = QNetworkReply::TimeoutError;
348+
response = "";
349+
error_str = "Timed out waiting for response";
350+
disconnect(manager, nullptr, nullptr, nullptr);
351+
reply->abort();
352+
reply->deleteLater();
353+
354+
emit on_execution_finished(this);
355+
}
330356
QSslConfiguration* OAIHttpRequestWorker::sslDefaultConfiguration;
331357

332358

samples/client/petstore/cpp-qt5/client/OAIHttpRequest.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include <QObject>
2323
#include <QString>
24+
#include <QTimer>
2425
#include <QMap>
2526
#include <QNetworkAccessManager>
2627
#include <QNetworkReply>
@@ -69,24 +70,25 @@ class OAIHttpRequestWorker : public QObject {
6970
QByteArray response;
7071
QNetworkReply::NetworkError error_type;
7172
QString error_str;
72-
73+
QTimer *timer;
7374
explicit OAIHttpRequestWorker(QObject *parent = nullptr);
7475
virtual ~OAIHttpRequestWorker();
7576

7677
QMap<QByteArray, QByteArray> getResponseHeaders() const;
7778
QString http_attribute_encode(QString attribute_name, QString input);
7879
void execute(OAIHttpRequestInput *input);
7980
static QSslConfiguration* sslDefaultConfiguration;
80-
81+
void setTimeOut(int tout);
8182
signals:
8283
void on_execution_finished(OAIHttpRequestWorker *worker);
8384

8485
private:
8586
QNetworkAccessManager *manager;
8687
QMap<QByteArray, QByteArray> headers;
88+
int timeout;
89+
void on_manager_timeout(QNetworkReply *reply);
8790
private slots:
88-
void on_manager_finished(QNetworkReply *reply);
89-
91+
void on_manager_finished(QNetworkReply *reply);
9092
};
9193

9294
}

0 commit comments

Comments
 (0)