refactor sendRequestMethod to QPromisse

This commit is contained in:
Andrei Yankovich 2024-12-03 21:19:33 +01:00
parent dd6eb8b815
commit c607bde041
4 changed files with 105 additions and 44 deletions

View File

@ -0,0 +1,33 @@
//#
//# Copyright (C) 2023-2024 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include "httpexception.h"
HttpException::HttpException(QNetworkReply::NetworkError code,
const QByteArray &erroString) {
if (erroString.size()) {
_errText = erroString;
} else {
_errText = QByteArray("Http request fonoshed with code: ").
append(QString::number(code).toLatin1());
}
}
const char *HttpException::what() const noexcept {
return _errText.constData();
}
void HttpException::raise() const {
throw *this;
}
QException *HttpException::clone() const {
return new HttpException(QNetworkReply::NetworkError(0),
_errText);
}

View File

@ -0,0 +1,36 @@
//#
//# Copyright (C) 2023-2024 QuasarApp.
//# Distributed under the GPLv3 software license, see the accompanying
//# Everyone is permitted to copy and distribute verbatim copies
//# of this license document, but changing it is not allowed.
//#
#include <QException>
#include <QNetworkReply>
#ifndef HTTPEXCEPTION_H
#define HTTPEXCEPTION_H
/**
* @brief The HttpException class is base exaption that will raise on all errors of the HTTP protocol,
*/
class HttpException: public QException
{
public:
HttpException(QNetworkReply::NetworkError code, const QByteArray& erroString = {});
// exception interface
public:
const char *what() const noexcept;
// QException interface
public:
void raise() const;
QException *clone() const;
private:
QByteArray _errText;
};
#endif // HTTPEXCEPTION_H

View File

@ -5,16 +5,18 @@
//# of this license document, but changing it is not allowed.
//#
#include "httpexception.h"
#include "ibot.h"
#include "qstandardpaths.h"
#include <QNetworkReply>
#include <QPromise>
namespace qTbot {
IBot::IBot() {
_manager = new QNetworkAccessManager();
_manager->setAutoDeleteReplies(false);
_manager->setAutoDeleteReplies(true);
}
IBot::~IBot() {
@ -48,12 +50,11 @@ void IBot::incomeNewUpdate(const QSharedPointer<iUpdate> &message) {
}
}
QSharedPointer<QNetworkReply>
QFuture<QByteArray>
IBot::sendRequest(const QSharedPointer<iRequest> &rquest) {
if (!rquest)
return nullptr;
doRemoveFinishedRequests();
if (!rquest)
return {};
auto && url = makeUrl(rquest);
@ -61,17 +62,13 @@ IBot::sendRequest(const QSharedPointer<iRequest> &rquest) {
qDebug() << url;
#endif
QSharedPointer<QNetworkReply> networkReplay;
QNetworkReply* networkReplay = nullptr;
QSharedPointer<QHttpMultiPart> httpData;
switch (rquest->method()) {
case iRequest::Get: {
auto reply = _manager->get(QNetworkRequest(url));
networkReplay = _manager->get(QNetworkRequest(url));
// we control replay object wia shared pointers.
reply->setParent(nullptr);
networkReplay.reset(reply);
break;
}
@ -85,38 +82,43 @@ IBot::sendRequest(const QSharedPointer<iRequest> &rquest) {
httpData = rquest->argsToMultipartFormData();
if (httpData) {
auto reply = _manager->post(netRequest, httpData.data());
networkReplay = _manager->post(netRequest, httpData.data());
// we control replay object wia shared pointers.
reply->setParent(nullptr);
networkReplay.reset(reply);
} else {
return nullptr;
return {};
}
break;
}
size_t address = reinterpret_cast<size_t>(networkReplay.get());
_replayStorage[address] = networkReplay;
if (!networkReplay) {
return {};
}
connect(networkReplay.get(), &QNetworkReply::finished, this,
[this, address, httpData]() {
_toRemove.push_back(address);
});
auto&& promise = QSharedPointer<QPromise<QByteArray>>::create();
connect(networkReplay.get(), &QNetworkReply::errorOccurred, this,
[this, address](QNetworkReply::NetworkError err){
qWarning() << "The reqeust " << address << " finished with error code : " << err;
if (auto&& replay = _replayStorage.value(address)) {
qWarning() << replay->errorString();
}
networkReplay->connect(networkReplay, &QNetworkReply::finished, [networkReplay, promise](){
promise->addResult(networkReplay->readAll());
promise->finish();
});
_toRemove.push_back(address);
});
networkReplay->connect(networkReplay, &QNetworkReply::errorOccurred, [networkReplay, promise](QNetworkReply::NetworkError ){
promise->setException(HttpException(networkReplay->error(), networkReplay->errorString().toLatin1()));
promise->finish();
});
return networkReplay;
auto && setProggress = [promise](qint64 bytesCurrent, qint64 bytesTotal){
if (promise->future().progressMaximum() != bytesTotal)
promise->setProgressRange(0, bytesTotal);
promise->setProgressValue(bytesCurrent);
};
networkReplay->connect(networkReplay, &QNetworkReply::downloadProgress, setProggress);
networkReplay->connect(networkReplay, &QNetworkReply::uploadProgress, setProggress);
return promise->future();
}
void IBot::markUpdateAsProcessed(const QSharedPointer<iUpdate> &message) {
@ -139,14 +141,6 @@ void IBot::handleIncomeNewUpdate(const QSharedPointer<iUpdate> & message) {
emit sigReceiveUpdate(message);
}
void IBot::doRemoveFinishedRequests() {
for (auto address: std::as_const(_toRemove)) {
_replayStorage.remove(address);
}
_toRemove.clear();
}
QSet<unsigned long long> IBot::processed() const {
return _processed;
}

View File

@ -23,6 +23,7 @@
#include <QNetworkReply>
#include <QObject>
#include <QSharedPointer>
#include <qfuture.h>
namespace qTbot {
@ -177,7 +178,7 @@ protected:
* @return shared pointer to the request replay.
* @note The raplay will be removed from local storage only after error or finishing, If you want to save replay just make local copy of the shared pointer.
*/
QSharedPointer<QNetworkReply>
QFuture<QByteArray>
sendRequest(const QSharedPointer<iRequest>& rquest);
/**
@ -234,7 +235,6 @@ signals:
void sigStopRequire();
private:
void doRemoveFinishedRequests();
QByteArray _token;
QString _name;
@ -242,8 +242,6 @@ private:
QSet<unsigned long long> _processed;
QNetworkAccessManager *_manager = nullptr;
QMap<size_t,QSharedPointer<QNetworkReply>> _replayStorage;
QList<size_t> _toRemove;
};