ClickHouse/src/Storages/RabbitMQ/RabbitMQHandler.cpp

76 lines
2.0 KiB
C++
Raw Normal View History

#include <common/logger_useful.h>
#include <Storages/RabbitMQ/RabbitMQHandler.h>
namespace DB
{
2020-06-04 06:22:53 +00:00
enum
{
Lock_timeout = 50,
Max_threads_to_pass = 10
};
RabbitMQHandler::RabbitMQHandler(event_base * evbase_, Poco::Logger * log_) :
LibEventHandler(evbase_),
evbase(evbase_),
log(log_)
{
}
2020-05-31 09:34:57 +00:00
void RabbitMQHandler::onError(AMQP::TcpConnection * connection, const char * message)
{
2020-05-26 20:43:20 +00:00
LOG_ERROR(log, "Library error report: {}", message);
2020-06-01 20:48:24 +00:00
2020-06-04 06:22:53 +00:00
if (!connection->usable() || !connection->ready())
2020-05-31 09:34:57 +00:00
{
2020-06-04 06:22:53 +00:00
LOG_ERROR(log, "Connection lost completely");
2020-05-31 09:34:57 +00:00
}
stop();
}
void RabbitMQHandler::start(std::atomic<bool> & check_param)
{
2020-06-04 06:22:53 +00:00
/* The object of this class is shared between concurrent consumers (who share the same connection == share the same
* event loop). But the loop should not be attempted to start if it is already running.
*/
2020-06-04 06:22:53 +00:00
if (mutex_before_event_loop.try_lock_for(std::chrono::milliseconds(Lock_timeout)))
{
/* The callback, which changes this variable, could have already been activated by another thread while we waited
* for the mutex to unlock (as it runs all active events on the connection). This means that there is no need to
* start event loop again.
*/
if (!check_param)
{
event_base_loop(evbase, EVLOOP_NONBLOCK);
}
2020-06-04 06:22:53 +00:00
mutex_before_event_loop.unlock();
}
else
{
if (++count_passed == Max_threads_to_pass)
{
/* Event loop is blocking to the thread that started it and it is not good to block one single thread as it loops
* untill there are no active events, but there can be too many of them for one thread to be blocked for so long.
*/
stop();
count_passed = 0;
}
}
}
void RabbitMQHandler::stop()
{
2020-06-04 06:22:53 +00:00
if (mutex_before_loop_stop.try_lock_for(std::chrono::milliseconds(0)))
{
event_base_loopbreak(evbase);
mutex_before_loop_stop.unlock();
}
}
}