_DEBUG-test ConcurrentSender generic handlers.

This commit is contained in:
John Preston 2018-06-17 21:29:46 +01:00
parent 1bfe409c93
commit c7aa5ed544

View File

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