async_run

Reviewers: ivica

Reviewed By: ivica

Subscribers: korina

Differential Revision: https://repo.mireo.local/D27342
This commit is contained in:
Bruno Iljazovic
2024-01-16 13:04:21 +01:00
parent 2f6751d162
commit 4f87b27861
29 changed files with 398 additions and 85 deletions

View File

@@ -181,6 +181,9 @@ public:
return resend();
}
if (ec == asio::error::no_recovery)
_svc.cancel();
// errors, if any, are propagated to ops
for (auto& op : write_queue)
op.complete(ec);

View File

@@ -184,7 +184,7 @@ public:
private:
using tls_context_type = TlsContext;
using receive_channel = asio::experimental::basic_concurrent_channel<
asio::any_io_executor,
executor_type,
channel_traits<>,
void (error_code, std::string, std::string, publish_props)
>;
@@ -204,6 +204,8 @@ private:
template <typename ClientService>
friend class re_auth_op;
executor_type _executor;
stream_context_type _stream_context;
stream_type _stream;
@@ -219,6 +221,8 @@ private:
asio::cancellation_signal _cancel_ping;
asio::cancellation_signal _cancel_sentry;
asio::any_completion_handler<void(error_code)> _run_handler;
public:
client_service(
@@ -226,6 +230,7 @@ public:
const std::string& /* cnf */,
tls_context_type tls_context = {}
) :
_executor(ex),
_stream_context(std::move(tls_context)),
_stream(ex, _stream_context),
_replies(ex),
@@ -235,7 +240,7 @@ public:
{}
executor_type get_executor() const noexcept {
return _stream.get_executor();
return _executor;
}
template <
@@ -302,7 +307,18 @@ public:
return _stream_context.connack_properties();
}
void run() {
template <typename Handler>
void run(Handler&& handler) {
_executor = asio::get_associated_executor(handler, _executor);
_run_handler = std::move(handler);
auto slot = asio::get_associated_cancellation_slot(_run_handler);
if (slot.is_connected()) {
using c_t = asio::cancellation_type_t;
slot.assign([&svc = *this](c_t c) {
if ((c & c_t::terminal) != c_t::none)
svc.cancel();
});
}
_stream.open();
_rec_channel.reset();
}
@@ -320,6 +336,8 @@ public:
}
void cancel() {
if (!_run_handler) return;
_cancel_ping.emit(asio::cancellation_type::terminal);
_cancel_sentry.emit(asio::cancellation_type::terminal);
@@ -327,6 +345,15 @@ public:
_replies.cancel_unanswered();
_async_sender.cancel();
_stream.close();
asio::get_associated_cancellation_slot(_run_handler).clear();
asio::post(
get_executor(),
asio::prepend(
std::move(_run_handler),
asio::error::operation_aborted
)
);
}
uint16_t allocate_pid() {
@@ -420,9 +447,20 @@ public:
template <typename CompletionToken>
decltype(auto) async_channel_receive(CompletionToken&& token) {
// sig = void (error_code, std::string, std::string, publish_props)
return _rec_channel.async_receive(
std::forward<CompletionToken>(token)
using Signature =
void(error_code, std::string, std::string, publish_props);
auto initiation = [] (auto handler, self_type& self) {
auto ex = asio::get_associated_executor(
handler, self.get_executor()
);
return self._rec_channel.async_receive(
asio::bind_executor(ex, std::move(handler))
);
};
return asio::async_initiate<CompletionToken, Signature> (
initiation, token, std::ref(*this)
);
}

View File

@@ -259,7 +259,7 @@ inline std::string encode_subscribe(
inline std::string encode_suback(
uint16_t packet_id,
std::vector<uint8_t>& reason_codes,
const std::vector<uint8_t>& reason_codes,
const suback_props& props
) {
@@ -319,7 +319,7 @@ inline std::string encode_unsubscribe(
inline std::string encode_unsuback(
uint16_t packet_id,
std::vector<uint8_t>& reason_codes,
const std::vector<uint8_t>& reason_codes,
const unsuback_props& props
) {

View File

@@ -64,10 +64,10 @@ public:
"Malformed Packet received from the Server"
);
if (
ec == asio::error::operation_aborted ||
ec == asio::error::no_recovery
)
if (ec == asio::error::no_recovery)
return _svc_ptr->cancel();
if (ec == asio::error::operation_aborted)
return;
dispatch(control_code, first, last);
@@ -115,6 +115,8 @@ private:
re_auth_op { _svc_ptr }.perform(std::move(*rv));
}
break;
default:
assert(false);
}
perform();