mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-16 11:22:12 +00:00
125 lines
3.0 KiB
C++
125 lines
3.0 KiB
C++
#include "RabbitMQConnection.h"
|
|
|
|
#include <common/logger_useful.h>
|
|
#include <IO/WriteHelpers.h>
|
|
|
|
|
|
namespace DB
|
|
{
|
|
|
|
static const auto CONNECT_SLEEP = 200;
|
|
static const auto RETRIES_MAX = 20;
|
|
|
|
|
|
RabbitMQConnection::RabbitMQConnection(const RabbitMQConfiguration & configuration_, Poco::Logger * log_)
|
|
: configuration(configuration_)
|
|
, log(log_)
|
|
, event_handler(loop.getLoop(), log)
|
|
{
|
|
}
|
|
|
|
String RabbitMQConnection::connectionInfoForLog() const
|
|
{
|
|
return configuration.host + ':' + toString(configuration.port);
|
|
}
|
|
|
|
bool RabbitMQConnection::isConnected()
|
|
{
|
|
std::lock_guard lock(mutex);
|
|
return isConnectedImpl();
|
|
}
|
|
|
|
bool RabbitMQConnection::connect()
|
|
{
|
|
std::lock_guard lock(mutex);
|
|
connectImpl();
|
|
return event_handler.connectionRunning();
|
|
}
|
|
|
|
bool RabbitMQConnection::reconnect()
|
|
{
|
|
std::lock_guard lock(mutex);
|
|
if (isConnectedImpl())
|
|
return true;
|
|
|
|
disconnectImpl();
|
|
|
|
/// This will force immediate closure if not yet closed
|
|
if (!connection->closed())
|
|
connection->close(true);
|
|
|
|
LOG_TRACE(log, "Trying to restore connection to {}", connectionInfoForLog());
|
|
connectImpl();
|
|
|
|
return event_handler.connectionRunning();
|
|
}
|
|
|
|
ChannelPtr RabbitMQConnection::createChannel()
|
|
{
|
|
std::lock_guard lock(mutex);
|
|
|
|
if (!isConnectedImpl())
|
|
return nullptr;
|
|
|
|
return std::make_unique<AMQP::TcpChannel>(connection.get());
|
|
}
|
|
|
|
void RabbitMQConnection::disconnect(bool immediately)
|
|
{
|
|
std::lock_guard lock(mutex);
|
|
disconnectImpl(immediately);
|
|
}
|
|
|
|
void RabbitMQConnection::heartbeat()
|
|
{
|
|
std::lock_guard lock(mutex);
|
|
connection->heartbeat();
|
|
}
|
|
|
|
bool RabbitMQConnection::closed()
|
|
{
|
|
std::lock_guard lock(mutex);
|
|
return connection->closed();
|
|
}
|
|
|
|
bool RabbitMQConnection::isConnectedImpl() const
|
|
{
|
|
return event_handler.connectionRunning() && connection->usable();
|
|
}
|
|
|
|
void RabbitMQConnection::connectImpl()
|
|
{
|
|
if (configuration.connection_string.empty())
|
|
{
|
|
AMQP::Login login(configuration.username, configuration.password);
|
|
AMQP::Address address(configuration.host, configuration.port, login, configuration.vhost, configuration.secure);
|
|
connection = std::make_unique<AMQP::TcpConnection>(&event_handler, address);
|
|
}
|
|
else
|
|
{
|
|
AMQP::Address address(configuration.connection_string);
|
|
connection = std::make_unique<AMQP::TcpConnection>(&event_handler, address);
|
|
}
|
|
|
|
auto cnt_retries = 0;
|
|
while (!connection->ready() && cnt_retries++ != RETRIES_MAX)
|
|
{
|
|
event_handler.iterateLoop();
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(CONNECT_SLEEP));
|
|
}
|
|
}
|
|
|
|
void RabbitMQConnection::disconnectImpl(bool immediately)
|
|
{
|
|
connection->close(immediately);
|
|
|
|
/** Connection is not closed immediately (firstly, all pending operations are completed, and then
|
|
* an AMQP closing-handshake is performed). But cannot open a new connection until previous one is properly closed
|
|
*/
|
|
size_t cnt_retries = 0;
|
|
while (!connection->closed() && cnt_retries++ != RETRIES_MAX)
|
|
event_handler.iterateLoop();
|
|
}
|
|
|
|
}
|