mirror of https://github.com/procxx/kepka.git
_DEBUG-test ConcurrentSender generic handlers.
This commit is contained in:
parent
1bfe409c93
commit
c7aa5ed544
|
@ -13,6 +13,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "base/flat_map.h"
|
#include "base/flat_map.h"
|
||||||
#include "mtproto/core_types.h"
|
#include "mtproto/core_types.h"
|
||||||
|
|
||||||
|
#ifndef _DEBUG
|
||||||
|
#define MTP_SENDER_USE_GENERIC_HANDLERS
|
||||||
|
#endif // !_DEBUG
|
||||||
|
|
||||||
class RPCError;
|
class RPCError;
|
||||||
|
|
||||||
namespace MTP {
|
namespace MTP {
|
||||||
|
@ -21,7 +25,8 @@ class Instance;
|
||||||
|
|
||||||
class ConcurrentSender : public base::has_weak_ptr {
|
class ConcurrentSender : public base::has_weak_ptr {
|
||||||
template <typename ...Args>
|
template <typename ...Args>
|
||||||
static constexpr bool is_callable_v = rpl::details::is_callable_v<Args...>;
|
static constexpr bool is_callable_v
|
||||||
|
= rpl::details::is_callable_v<Args...>;
|
||||||
|
|
||||||
template <typename Method>
|
template <typename Method>
|
||||||
auto with_instance(Method &&method)
|
auto with_instance(Method &&method)
|
||||||
|
@ -101,7 +106,7 @@ public:
|
||||||
[[nodiscard]] SpecificRequestBuilder &afterDelay(
|
[[nodiscard]] SpecificRequestBuilder &afterDelay(
|
||||||
TimeMs ms) noexcept;
|
TimeMs ms) noexcept;
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifndef MTP_SENDER_USE_GENERIC_HANDLERS
|
||||||
// Allow code completion to show response type.
|
// Allow code completion to show response type.
|
||||||
[[nodiscard]] SpecificRequestBuilder &done(FnMut<void()> &&handler);
|
[[nodiscard]] SpecificRequestBuilder &done(FnMut<void()> &&handler);
|
||||||
[[nodiscard]] SpecificRequestBuilder &done(FnMut<void(
|
[[nodiscard]] SpecificRequestBuilder &done(FnMut<void(
|
||||||
|
@ -119,12 +124,12 @@ public:
|
||||||
RPCError &&)> &&handler);
|
RPCError &&)> &&handler);
|
||||||
[[nodiscard]] SpecificRequestBuilder &fail(FnMut<void(
|
[[nodiscard]] SpecificRequestBuilder &fail(FnMut<void(
|
||||||
RPCError &&)> &&handler);
|
RPCError &&)> &&handler);
|
||||||
#else // _DEBUG
|
#else // !MTP_SENDER_USE_GENERIC_HANDLERS
|
||||||
template <typename Handler>
|
template <typename Handler>
|
||||||
[[nodiscard]] SpecificRequestBuilder &done(Handler &&handler);
|
[[nodiscard]] SpecificRequestBuilder &done(Handler &&handler);
|
||||||
template <typename Handler>
|
template <typename Handler>
|
||||||
[[nodiscard]] SpecificRequestBuilder &fail(Handler &&handler);
|
[[nodiscard]] SpecificRequestBuilder &fail(Handler &&handler);
|
||||||
#endif // _DEBUG
|
#endif // MTP_SENDER_USE_GENERIC_HANDLERS
|
||||||
|
|
||||||
[[nodiscard]] SpecificRequestBuilder &handleFloodErrors() noexcept;
|
[[nodiscard]] SpecificRequestBuilder &handleFloodErrors() noexcept;
|
||||||
[[nodiscard]] SpecificRequestBuilder &handleAllErrors() noexcept;
|
[[nodiscard]] SpecificRequestBuilder &handleAllErrors() noexcept;
|
||||||
|
@ -142,14 +147,14 @@ public:
|
||||||
|
|
||||||
class SentRequestWrap {
|
class SentRequestWrap {
|
||||||
public:
|
public:
|
||||||
void cancel() {
|
void cancel();
|
||||||
_sender->senderRequestCancel(_requestId);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class ConcurrentSender;
|
friend class ConcurrentSender;
|
||||||
SentRequestWrap(not_null<ConcurrentSender*> sender, mtpRequestId requestId) : _sender(sender), _requestId(requestId) {
|
SentRequestWrap(
|
||||||
}
|
not_null<ConcurrentSender*> sender,
|
||||||
|
mtpRequestId requestId);
|
||||||
|
|
||||||
not_null<ConcurrentSender*> _sender;
|
not_null<ConcurrentSender*> _sender;
|
||||||
mtpRequestId _requestId = 0;
|
mtpRequestId _requestId = 0;
|
||||||
|
|
||||||
|
@ -164,11 +169,7 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] SentRequestWrap request(mtpRequestId requestId) noexcept;
|
[[nodiscard]] SentRequestWrap request(mtpRequestId requestId) noexcept;
|
||||||
|
|
||||||
[[nodiscard]] auto requestCanceller() noexcept {
|
[[nodiscard]] auto requestCanceller() noexcept;
|
||||||
return [=](mtpRequestId requestId) {
|
|
||||||
request(requestId).cancel();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
~ConcurrentSender();
|
~ConcurrentSender();
|
||||||
|
|
||||||
|
@ -197,7 +198,8 @@ private:
|
||||||
|
|
||||||
template <typename Response, typename InvokeFullDone>
|
template <typename Response, typename InvokeFullDone>
|
||||||
void ConcurrentSender::RequestBuilder::setDoneHandler(
|
void ConcurrentSender::RequestBuilder::setDoneHandler(
|
||||||
InvokeFullDone &&invoke) noexcept {
|
InvokeFullDone &&invoke
|
||||||
|
) noexcept {
|
||||||
_handlers.done = [handler = std::move(invoke)](
|
_handlers.done = [handler = std::move(invoke)](
|
||||||
mtpRequestId requestId,
|
mtpRequestId requestId,
|
||||||
bytes::const_span result) mutable {
|
bytes::const_span result) mutable {
|
||||||
|
@ -214,37 +216,40 @@ void ConcurrentSender::RequestBuilder::setDoneHandler(
|
||||||
|
|
||||||
template <typename InvokeFullFail>
|
template <typename InvokeFullFail>
|
||||||
void ConcurrentSender::RequestBuilder::setFailHandler(
|
void ConcurrentSender::RequestBuilder::setFailHandler(
|
||||||
InvokeFullFail &&invoke) noexcept {
|
InvokeFullFail &&invoke
|
||||||
|
) noexcept {
|
||||||
_handlers.fail = std::move(invoke);
|
_handlers.fail = std::move(invoke);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Request>
|
template <typename Request>
|
||||||
ConcurrentSender::SpecificRequestBuilder<Request>::SpecificRequestBuilder(
|
ConcurrentSender::SpecificRequestBuilder<Request>::SpecificRequestBuilder(
|
||||||
not_null<ConcurrentSender*> sender,
|
not_null<ConcurrentSender*> sender,
|
||||||
Request &&request) noexcept
|
Request &&request
|
||||||
: RequestBuilder(sender, mtpRequestData::serialize(request)) {
|
) noexcept : RequestBuilder(sender, mtpRequestData::serialize(request)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Request>
|
template <typename Request>
|
||||||
[[nodiscard]] auto ConcurrentSender::SpecificRequestBuilder<Request>::toDC(
|
auto ConcurrentSender::SpecificRequestBuilder<Request>::toDC(
|
||||||
ShiftedDcId dcId) noexcept -> SpecificRequestBuilder & {
|
ShiftedDcId dcId
|
||||||
|
) noexcept -> SpecificRequestBuilder & {
|
||||||
setToDC(dcId);
|
setToDC(dcId);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Request>
|
template <typename Request>
|
||||||
[[nodiscard]] auto ConcurrentSender::SpecificRequestBuilder<Request>::afterDelay(
|
auto ConcurrentSender::SpecificRequestBuilder<Request>::afterDelay(
|
||||||
TimeMs ms) noexcept -> SpecificRequestBuilder & {
|
TimeMs ms
|
||||||
|
) noexcept -> SpecificRequestBuilder & {
|
||||||
setCanWait(ms);
|
setCanWait(ms);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifndef MTP_SENDER_USE_GENERIC_HANDLERS
|
||||||
// Allow code completion to show response type.
|
// Allow code completion to show response type.
|
||||||
template <typename Request>
|
template <typename Request>
|
||||||
[[nodiscard]] auto ConcurrentSender::SpecificRequestBuilder<Request>::done(
|
auto ConcurrentSender::SpecificRequestBuilder<Request>::done(
|
||||||
FnMut<void(Response &&)> &&handler)
|
FnMut<void(Response &&)> &&handler
|
||||||
-> SpecificRequestBuilder & {
|
) -> SpecificRequestBuilder & {
|
||||||
setDoneHandler<Response>([handler = std::move(handler)](
|
setDoneHandler<Response>([handler = std::move(handler)](
|
||||||
mtpRequestId requestId,
|
mtpRequestId requestId,
|
||||||
Response &&result) mutable {
|
Response &&result) mutable {
|
||||||
|
@ -254,16 +259,17 @@ template <typename Request>
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Request>
|
template <typename Request>
|
||||||
[[nodiscard]] auto ConcurrentSender::SpecificRequestBuilder<Request>::done(
|
auto ConcurrentSender::SpecificRequestBuilder<Request>::done(
|
||||||
FnMut<void(mtpRequestId, Response &&)> &&handler)
|
FnMut<void(mtpRequestId, Response &&)> &&handler
|
||||||
-> SpecificRequestBuilder & {
|
) -> SpecificRequestBuilder & {
|
||||||
setDoneHandler<Response>(std::move(handler));
|
setDoneHandler<Response>(std::move(handler));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Request>
|
template <typename Request>
|
||||||
[[nodiscard]] auto ConcurrentSender::SpecificRequestBuilder<Request>::done(
|
auto ConcurrentSender::SpecificRequestBuilder<Request>::done(
|
||||||
FnMut<void(mtpRequestId)> &&handler) -> SpecificRequestBuilder & {
|
FnMut<void(mtpRequestId)> &&handler
|
||||||
|
) -> SpecificRequestBuilder & {
|
||||||
setDoneHandler<Response>([handler = std::move(handler)](
|
setDoneHandler<Response>([handler = std::move(handler)](
|
||||||
mtpRequestId requestId,
|
mtpRequestId requestId,
|
||||||
Response &&result) mutable {
|
Response &&result) mutable {
|
||||||
|
@ -273,8 +279,9 @@ template <typename Request>
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Request>
|
template <typename Request>
|
||||||
[[nodiscard]] auto ConcurrentSender::SpecificRequestBuilder<Request>::done(
|
auto ConcurrentSender::SpecificRequestBuilder<Request>::done(
|
||||||
FnMut<void()> &&handler) -> SpecificRequestBuilder & {
|
FnMut<void()> &&handler
|
||||||
|
) -> SpecificRequestBuilder & {
|
||||||
setDoneHandler<Response>([handler = std::move(handler)](
|
setDoneHandler<Response>([handler = std::move(handler)](
|
||||||
mtpRequestId requestId,
|
mtpRequestId requestId,
|
||||||
Response &&result) mutable {
|
Response &&result) mutable {
|
||||||
|
@ -284,8 +291,9 @@ template <typename Request>
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Request>
|
template <typename Request>
|
||||||
[[nodiscard]] auto ConcurrentSender::SpecificRequestBuilder<Request>::fail(
|
auto ConcurrentSender::SpecificRequestBuilder<Request>::fail(
|
||||||
FnMut<void(RPCError &&)> &&handler) -> SpecificRequestBuilder & {
|
FnMut<void(RPCError &&)> &&handler
|
||||||
|
) -> SpecificRequestBuilder & {
|
||||||
setFailHandler([handler = std::move(handler)](
|
setFailHandler([handler = std::move(handler)](
|
||||||
mtpRequestId requestId,
|
mtpRequestId requestId,
|
||||||
RPCError &&error) mutable {
|
RPCError &&error) mutable {
|
||||||
|
@ -295,16 +303,17 @@ template <typename Request>
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Request>
|
template <typename Request>
|
||||||
[[nodiscard]] auto ConcurrentSender::SpecificRequestBuilder<Request>::fail(
|
auto ConcurrentSender::SpecificRequestBuilder<Request>::fail(
|
||||||
FnMut<void(mtpRequestId, RPCError &&)> &&handler)
|
FnMut<void(mtpRequestId, RPCError &&)> &&handler
|
||||||
-> SpecificRequestBuilder & {
|
) -> SpecificRequestBuilder & {
|
||||||
setFailHandler(std::move(handler));
|
setFailHandler(std::move(handler));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Request>
|
template <typename Request>
|
||||||
[[nodiscard]] auto ConcurrentSender::SpecificRequestBuilder<Request>::fail(
|
auto ConcurrentSender::SpecificRequestBuilder<Request>::fail(
|
||||||
FnMut<void(mtpRequestId)> &&handler) -> SpecificRequestBuilder & {
|
FnMut<void(mtpRequestId)> &&handler
|
||||||
|
) -> SpecificRequestBuilder & {
|
||||||
setFailHandler([handler = std::move(handler)](
|
setFailHandler([handler = std::move(handler)](
|
||||||
mtpRequestId requestId,
|
mtpRequestId requestId,
|
||||||
RPCError &&error) mutable {
|
RPCError &&error) mutable {
|
||||||
|
@ -314,8 +323,9 @@ template <typename Request>
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Request>
|
template <typename Request>
|
||||||
[[nodiscard]] auto ConcurrentSender::SpecificRequestBuilder<Request>::fail(
|
auto ConcurrentSender::SpecificRequestBuilder<Request>::fail(
|
||||||
FnMut<void()> &&handler) -> SpecificRequestBuilder & {
|
FnMut<void()> &&handler
|
||||||
|
) -> SpecificRequestBuilder & {
|
||||||
setFailHandler([handler = std::move(handler)](
|
setFailHandler([handler = std::move(handler)](
|
||||||
mtpRequestId requestId,
|
mtpRequestId requestId,
|
||||||
RPCError &&error) mutable {
|
RPCError &&error) mutable {
|
||||||
|
@ -323,11 +333,12 @@ template <typename Request>
|
||||||
});
|
});
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#else // _DEBUG
|
#else // !MTP_SENDER_USE_GENERIC_HANDLERS
|
||||||
template <typename Request>
|
template <typename Request>
|
||||||
template <typename Handler>
|
template <typename Handler>
|
||||||
[[nodiscard]] auto ConcurrentSender::SpecificRequestBuilder<Request>::done(
|
auto ConcurrentSender::SpecificRequestBuilder<Request>::done(
|
||||||
Handler &&handler) -> SpecificRequestBuilder & {
|
Handler &&handler
|
||||||
|
) -> SpecificRequestBuilder & {
|
||||||
using Response = typename Request::ResponseType;
|
using Response = typename Request::ResponseType;
|
||||||
constexpr auto takesFull = rpl::details::is_callable_plain_v<
|
constexpr auto takesFull = rpl::details::is_callable_plain_v<
|
||||||
Handler,
|
Handler,
|
||||||
|
@ -369,8 +380,9 @@ template <typename Handler>
|
||||||
|
|
||||||
template <typename Request>
|
template <typename Request>
|
||||||
template <typename Handler>
|
template <typename Handler>
|
||||||
[[nodiscard]] auto ConcurrentSender::SpecificRequestBuilder<Request>::fail(
|
auto ConcurrentSender::SpecificRequestBuilder<Request>::fail(
|
||||||
Handler &&handler) -> SpecificRequestBuilder & {
|
Handler &&handler
|
||||||
|
) -> SpecificRequestBuilder & {
|
||||||
constexpr auto takesFull = rpl::details::is_callable_plain_v<
|
constexpr auto takesFull = rpl::details::is_callable_plain_v<
|
||||||
Handler,
|
Handler,
|
||||||
mtpRequestId,
|
mtpRequestId,
|
||||||
|
@ -409,35 +421,53 @@ template <typename Handler>
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _DEBUG
|
#endif // MTP_SENDER_USE_GENERIC_HANDLERS
|
||||||
|
|
||||||
template <typename Request>
|
template <typename Request>
|
||||||
[[nodiscard]] auto ConcurrentSender::SpecificRequestBuilder<Request>::handleFloodErrors() noexcept
|
auto ConcurrentSender::SpecificRequestBuilder<Request>::handleFloodErrors(
|
||||||
-> SpecificRequestBuilder & {
|
) noexcept -> SpecificRequestBuilder & {
|
||||||
setFailSkipPolicy(FailSkipPolicy::HandleFlood);
|
setFailSkipPolicy(FailSkipPolicy::HandleFlood);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Request>
|
template <typename Request>
|
||||||
[[nodiscard]] auto ConcurrentSender::SpecificRequestBuilder<Request>::handleAllErrors() noexcept
|
auto ConcurrentSender::SpecificRequestBuilder<Request>::handleAllErrors(
|
||||||
-> SpecificRequestBuilder & {
|
) noexcept -> SpecificRequestBuilder & {
|
||||||
setFailSkipPolicy(FailSkipPolicy::HandleAll);
|
setFailSkipPolicy(FailSkipPolicy::HandleAll);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Request>
|
template <typename Request>
|
||||||
[[nodiscard]] auto ConcurrentSender::SpecificRequestBuilder<Request>::afterRequest(
|
auto ConcurrentSender::SpecificRequestBuilder<Request>::afterRequest(
|
||||||
mtpRequestId requestId) noexcept -> SpecificRequestBuilder & {
|
mtpRequestId requestId
|
||||||
|
) noexcept -> SpecificRequestBuilder & {
|
||||||
setAfter(requestId);
|
setAfter(requestId);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void ConcurrentSender::SentRequestWrap::cancel() {
|
||||||
|
_sender->senderRequestCancel(_requestId);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ConcurrentSender::SentRequestWrap::SentRequestWrap(
|
||||||
|
not_null<ConcurrentSender*> sender,
|
||||||
|
mtpRequestId requestId
|
||||||
|
) : _sender(sender)
|
||||||
|
, _requestId(requestId) {
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Request, typename, typename>
|
template <typename Request, typename, typename>
|
||||||
inline auto ConcurrentSender::request(Request &&request) noexcept
|
inline auto ConcurrentSender::request(Request &&request) noexcept
|
||||||
-> SpecificRequestBuilder<Request> {
|
-> SpecificRequestBuilder<Request> {
|
||||||
return SpecificRequestBuilder<Request>(this, std::move(request));
|
return SpecificRequestBuilder<Request>(this, std::move(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline auto ConcurrentSender::requestCanceller() noexcept {
|
||||||
|
return [=](mtpRequestId requestId) {
|
||||||
|
request(requestId).cancel();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
inline auto ConcurrentSender::request(mtpRequestId requestId) noexcept
|
inline auto ConcurrentSender::request(mtpRequestId requestId) noexcept
|
||||||
-> SentRequestWrap {
|
-> SentRequestWrap {
|
||||||
return SentRequestWrap(this, requestId);
|
return SentRequestWrap(this, requestId);
|
||||||
|
|
Loading…
Reference in New Issue