mirror of
https://github.com/transmission/transmission.git
synced 2025-12-19 18:08:31 +00:00
refactor: minor cleanup in RpcClient.cc (#7951)
* refactor: RpcClient::sendNetworkRequest() takes a QByteArray body arg * refactor: RpcClient::sendLocalRequest() takes a tr_variant const& req arg * refactor: move RpcClient::getNextTag() into an anonymous namespace * refactor: merge RpcClient::exec() and RpcClient::sendRequest() * refactor: remove unnecessary heap allocation in RpcClient::networkRequestFinished()
This commit is contained in:
115
qt/RpcClient.cc
115
qt/RpcClient.cc
@@ -4,6 +4,7 @@
|
||||
// License text can be found in the licenses/ folder.
|
||||
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
@@ -29,9 +30,33 @@ using ::trqt::variant_helpers::variantInit;
|
||||
namespace
|
||||
{
|
||||
|
||||
char constexpr const* const RequestDataPropertyKey{ "requestData" };
|
||||
char constexpr const* const RequestBodyKey{ "requestBody" };
|
||||
char constexpr const* const RequestFutureinterfacePropertyKey{ "requestReplyFutureInterface" };
|
||||
|
||||
[[nodiscard]] int64_t nextTag()
|
||||
{
|
||||
static int64_t tag = {};
|
||||
return tag++;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::pair<tr_variant, int64_t> buildRequest(tr_quark const method, tr_variant* args)
|
||||
{
|
||||
auto const tag = nextTag();
|
||||
|
||||
// TODO(ckerr): JSON-RPCize
|
||||
auto req = tr_variant::Map{ 3U };
|
||||
req.try_emplace(TR_KEY_method, tr_variant::unmanaged_string(method));
|
||||
req.try_emplace(TR_KEY_tag, tag);
|
||||
if (args != nullptr)
|
||||
{
|
||||
auto tmp = tr_variant{};
|
||||
std::swap(tmp, *args);
|
||||
req.try_emplace(TR_KEY_arguments, std::move(tmp));
|
||||
}
|
||||
|
||||
return { std::move(req), tag };
|
||||
}
|
||||
|
||||
TrVariantPtr createVariant()
|
||||
{
|
||||
return std::make_shared<tr_variant>();
|
||||
@@ -71,35 +96,31 @@ void RpcClient::start(QUrl const& url)
|
||||
request_.reset();
|
||||
}
|
||||
|
||||
RpcResponseFuture RpcClient::exec(tr_quark const method_key, tr_variant* args)
|
||||
RpcResponseFuture RpcClient::exec(tr_quark const method, tr_variant* args)
|
||||
{
|
||||
auto const method = tr_quark_get_string_view(method_key);
|
||||
auto const [req, tag] = buildRequest(method, args);
|
||||
|
||||
TrVariantPtr const json = createVariant();
|
||||
tr_variantInitDict(json.get(), 3);
|
||||
dictAdd(json.get(), TR_KEY_method, method);
|
||||
auto promise = QFutureInterface<RpcResponse>{};
|
||||
promise.setExpectedResultCount(1);
|
||||
promise.setProgressRange(0, 1);
|
||||
promise.setProgressValue(0);
|
||||
promise.reportStarted();
|
||||
|
||||
if (args != nullptr) // if args were passed in, use them
|
||||
if (session_ != nullptr)
|
||||
{
|
||||
auto* child = tr_variantDictFind(json.get(), TR_KEY_arguments);
|
||||
|
||||
if (child == nullptr)
|
||||
{
|
||||
child = tr_variantDictAddDict(json.get(), TR_KEY_arguments, 0);
|
||||
}
|
||||
|
||||
std::swap(*child, *args);
|
||||
sendLocalRequest(req, promise, tag);
|
||||
}
|
||||
else if (!url_.isEmpty())
|
||||
{
|
||||
auto const json = tr_variant_serde::json().compact().to_string(req);
|
||||
auto const body = QByteArray::fromStdString(json);
|
||||
sendNetworkRequest(body, promise);
|
||||
}
|
||||
|
||||
return sendRequest(json);
|
||||
return promise.future();
|
||||
}
|
||||
|
||||
int64_t RpcClient::getNextTag()
|
||||
{
|
||||
return next_tag_++;
|
||||
}
|
||||
|
||||
void RpcClient::sendNetworkRequest(TrVariantPtr req, QFutureInterface<RpcResponse> const& promise)
|
||||
void RpcClient::sendNetworkRequest(QByteArray const& body, QFutureInterface<RpcResponse> const& promise)
|
||||
{
|
||||
if (!request_)
|
||||
{
|
||||
@@ -117,9 +138,8 @@ void RpcClient::sendNetworkRequest(TrVariantPtr req, QFutureInterface<RpcRespons
|
||||
request_ = request;
|
||||
}
|
||||
|
||||
auto const json_data = QByteArray::fromStdString(tr_variant_serde::json().compact().to_string(*req));
|
||||
QNetworkReply* reply = networkAccessManager()->post(*request_, json_data);
|
||||
reply->setProperty(RequestDataPropertyKey, QVariant::fromValue(req));
|
||||
QNetworkReply* reply = networkAccessManager()->post(*request_, body);
|
||||
reply->setProperty(RequestBodyKey, body);
|
||||
reply->setProperty(RequestFutureinterfacePropertyKey, QVariant::fromValue(promise));
|
||||
|
||||
connect(reply, &QNetworkReply::downloadProgress, this, &RpcClient::dataReadProgress);
|
||||
@@ -135,21 +155,21 @@ void RpcClient::sendNetworkRequest(TrVariantPtr req, QFutureInterface<RpcRespons
|
||||
}
|
||||
|
||||
qInfo() << "Body:";
|
||||
qInfo() << json_data.constData();
|
||||
qInfo() << body.constData();
|
||||
}
|
||||
}
|
||||
|
||||
void RpcClient::sendLocalRequest(TrVariantPtr req, QFutureInterface<RpcResponse> const& promise, int64_t tag)
|
||||
void RpcClient::sendLocalRequest(tr_variant const& req, QFutureInterface<RpcResponse> const& promise, int64_t tag)
|
||||
{
|
||||
if (verbose_)
|
||||
{
|
||||
fmt::print("{:s}:{:d} sending req:\n{:s}\n", __FILE__, __LINE__, tr_variant_serde::json().to_string(*req));
|
||||
fmt::print("{:s}:{:d} sending req:\n{:s}\n", __FILE__, __LINE__, tr_variant_serde::json().to_string(req));
|
||||
}
|
||||
|
||||
local_requests_.try_emplace(tag, promise);
|
||||
tr_rpc_request_exec(
|
||||
session_,
|
||||
*req,
|
||||
req,
|
||||
[this](tr_session* /*sesson*/, tr_variant&& response)
|
||||
{
|
||||
if (verbose_)
|
||||
@@ -166,29 +186,6 @@ void RpcClient::sendLocalRequest(TrVariantPtr req, QFutureInterface<RpcResponse>
|
||||
});
|
||||
}
|
||||
|
||||
RpcResponseFuture RpcClient::sendRequest(TrVariantPtr json)
|
||||
{
|
||||
int64_t const tag = getNextTag();
|
||||
dictAdd(json.get(), TR_KEY_tag, tag);
|
||||
|
||||
QFutureInterface<RpcResponse> promise;
|
||||
promise.setExpectedResultCount(1);
|
||||
promise.setProgressRange(0, 1);
|
||||
promise.setProgressValue(0);
|
||||
promise.reportStarted();
|
||||
|
||||
if (session_ != nullptr)
|
||||
{
|
||||
sendLocalRequest(json, promise, tag);
|
||||
}
|
||||
else if (!url_.isEmpty())
|
||||
{
|
||||
sendNetworkRequest(json, promise);
|
||||
}
|
||||
|
||||
return promise.future();
|
||||
}
|
||||
|
||||
QNetworkAccessManager* RpcClient::networkAccessManager()
|
||||
{
|
||||
if (nam_ == nullptr)
|
||||
@@ -230,7 +227,7 @@ void RpcClient::networkRequestFinished(QNetworkReply* reply)
|
||||
session_id_ = QString::fromUtf8(reply->rawHeader(TR_RPC_SESSION_ID_HEADER));
|
||||
request_.reset();
|
||||
|
||||
sendNetworkRequest(reply->property(RequestDataPropertyKey).value<TrVariantPtr>(), promise);
|
||||
sendNetworkRequest(reply->property(RequestBodyKey).toByteArray(), promise);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -246,18 +243,16 @@ void RpcClient::networkRequestFinished(QNetworkReply* reply)
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const json_data = reply->readAll().trimmed().toStdString();
|
||||
auto const json = createVariant();
|
||||
auto result = RpcResponse{};
|
||||
auto const json = reply->readAll().trimmed().toStdString();
|
||||
auto response = RpcResponse{};
|
||||
|
||||
if (auto top = tr_variant_serde::json().parse(json_data); top)
|
||||
if (auto var = tr_variant_serde::json().parse(json))
|
||||
{
|
||||
std::swap(*json, *top);
|
||||
result = parseResponseData(*json);
|
||||
response = parseResponseData(*var);
|
||||
}
|
||||
|
||||
promise.setProgressValue(1);
|
||||
promise.reportFinished(&result);
|
||||
promise.reportFinished(&response);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,12 +85,10 @@ private slots:
|
||||
void localRequestFinished(TrVariantPtr response);
|
||||
|
||||
private:
|
||||
RpcResponseFuture sendRequest(TrVariantPtr json);
|
||||
QNetworkAccessManager* networkAccessManager();
|
||||
int64_t getNextTag();
|
||||
|
||||
void sendNetworkRequest(TrVariantPtr req, QFutureInterface<RpcResponse> const& promise);
|
||||
void sendLocalRequest(TrVariantPtr req, QFutureInterface<RpcResponse> const& promise, int64_t tag);
|
||||
void sendNetworkRequest(QByteArray const& body, QFutureInterface<RpcResponse> const& promise);
|
||||
void sendLocalRequest(tr_variant const& req, QFutureInterface<RpcResponse> const& promise, int64_t tag);
|
||||
[[nodiscard]] int64_t parseResponseTag(tr_variant& response) const;
|
||||
[[nodiscard]] RpcResponse parseResponseData(tr_variant& response) const;
|
||||
|
||||
@@ -101,7 +99,6 @@ private:
|
||||
QUrl url_;
|
||||
QNetworkAccessManager* nam_ = {};
|
||||
std::unordered_map<int64_t, QFutureInterface<RpcResponse>> local_requests_;
|
||||
int64_t next_tag_ = {};
|
||||
bool const verbose_ = qEnvironmentVariableIsSet("TR_RPC_VERBOSE");
|
||||
bool url_is_loopback_ = false;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user