2020-05-20 09:40:49 +00:00
|
|
|
#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
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2020-05-20 09:40:49 +00:00
|
|
|
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-20 09:40:49 +00:00
|
|
|
{
|
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
|
|
|
}
|
|
|
|
|
2020-05-20 09:40:49 +00:00
|
|
|
stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-05-29 16:04:44 +00:00
|
|
|
void RabbitMQHandler::start(std::atomic<bool> & check_param)
|
2020-05-20 09:40:49 +00:00
|
|
|
{
|
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-05-29 16:04:44 +00:00
|
|
|
*/
|
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-05-29 16:04:44 +00:00
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2020-05-20 09:40:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
2020-05-20 09:40:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|