I stucked on a question with boost. I have a factory with ioc and method that give access to ioc:
boost::asio::thread_pool::executor_type GetExecutor()
{
if (!m_ioc)
m_ioc = boost::make_shared<boost::asio::thread_pool>(2);
return m_ioc->get_executor();
}
I use the factory and this method to create TCP connection and use GetExecuter as constructor parameter:
TcpConnection::TcpConnection(
boost::asio::any_io_executor ex,
const eka::string8_t& to,
const eka::string8_t& port,
const Config& config)
: BaseConnection(to, port)
, m_socket(make_strand(ex), boost::asio::ip::tcp::v4())
, m_resolver(m_socket.get_executor())
, m_timeout(config.timeoutRequest)
{}
In Connect method I have MinimumPromise for controlling connection progress.
void TcpConnection::Connect(stopToken)
{
auto promise = std::make_shared<MinimumPromise>();
boost::asio::post(m_socket.get_executor(),
[this, promise, self = shared_from_this()]() mutable { DoConnect(promise); });
promise->Wait(m_timeout); // throws if doesn't establish connection in m_timeout
}
void TcpConnection::DoConnect(std::shared_ptr<MinimumPromise> promise)
{
m_resolver.async_resolve(
boost::asio::ip::tcp::v4(), m_to.c_str(), m_port.c_str(),
[this, promise, self = shared_from_this()]
(const boost::system::error_code& ec, boost::asio::ip::tcp::resolver::iterator eps) mutable {
if (ec) {
promise->SetException(std::make_exception_ptr(PREPARE_CONNECTION_EXCEPTION(ec, m_to)));
}
else {
boost::asio::async_connect(
m_socket, eps,
[this, promise, self = shared_from_this()]
(const boost::system::error_code& ec, boost::asio::ip::tcp::resolver::iterator it) mutable {
if (ec) {
promise->SetException(std::make_exception_ptr(PREPARE_CONNECTION_EXCEPTION(ec, m_to)));
}
else {
promise->Set();
}
});
}
});
}
Hypothetical situation: I wait in promise for 10 seconds, after promise throws exception. Posted connection task stay in queue - it will die on tcp timeout? How I can remove if from queue? If I destroy make_strand(ex) result it will clean queue? Will it affect other connections that use same threadpool? P.S. Idea of MinimalPromise is a timeout. I have TcpConnection with TLS and if connect TCP with TLS to TCP server program infinitly waiting for TLS handshake. This promise helping avoid this situation. Thank you
That's not a feature. You can however:
associate a cancellation_slot
with the handler and check the cancellation state from within your operation
stop() and restart() the entire execution context (e.g. asio::io_context::restart
)
Of course, you can (and probably should) use other means of queuing workloads.
Posted connection task stay in queue - it will die on tcp timeout?
See https://live.boost.org/doc/libs/1_87_0/doc/html/boost_asio/reference/ip__basic_resolver/cancel.html