2015-01-14 10:06:30 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <DB/Client/Connection.h>
|
2015-01-15 18:33:20 +00:00
|
|
|
|
#include <DB/Client/ConnectionPool.h>
|
2015-01-14 10:06:30 +00:00
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
|
{
|
2015-01-15 16:55:50 +00:00
|
|
|
|
/**
|
|
|
|
|
* Множество реплик одного шарда.
|
|
|
|
|
*/
|
2015-01-15 18:03:59 +00:00
|
|
|
|
class ShardReplicas final
|
2015-01-15 16:55:50 +00:00
|
|
|
|
{
|
2015-01-14 10:06:30 +00:00
|
|
|
|
public:
|
2015-01-15 18:33:20 +00:00
|
|
|
|
ShardReplicas(std::vector<ConnectionPool::Entry> & entries, Settings * settings_);
|
2015-01-14 10:06:30 +00:00
|
|
|
|
|
2015-01-15 18:03:59 +00:00
|
|
|
|
~ShardReplicas() = default;
|
2015-01-14 10:06:30 +00:00
|
|
|
|
|
2015-01-15 18:03:59 +00:00
|
|
|
|
ShardReplicas(const ShardReplicas &) = delete;
|
|
|
|
|
ShardReplicas & operator=(const ShardReplicas &) = delete;
|
2015-01-14 10:06:30 +00:00
|
|
|
|
|
2015-01-15 16:55:50 +00:00
|
|
|
|
/// Получить пакет от какой-нибудь реплики.
|
2015-01-14 10:06:30 +00:00
|
|
|
|
Connection::Packet receivePacket();
|
|
|
|
|
|
2015-01-15 16:55:50 +00:00
|
|
|
|
/// Отправить запрос ко всем репликам.
|
2015-01-14 10:06:30 +00:00
|
|
|
|
void sendQuery(const String & query, const String & query_id = "", UInt64 stage = QueryProcessingStage::Complete,
|
|
|
|
|
const Settings * settings_ = nullptr, bool with_pending_data = false);
|
|
|
|
|
|
2015-01-15 16:55:50 +00:00
|
|
|
|
/// Разорвать соединения ко всем репликам
|
2015-01-15 12:09:26 +00:00
|
|
|
|
void disconnect();
|
|
|
|
|
|
2015-01-15 16:55:50 +00:00
|
|
|
|
/// Отменить запросы у всех реплик
|
2015-01-15 12:09:26 +00:00
|
|
|
|
void sendCancel();
|
|
|
|
|
|
2015-01-15 16:55:50 +00:00
|
|
|
|
/// Для каждой реплики получить оставшиеся пакеты при отмене запроса.
|
2015-01-15 12:09:26 +00:00
|
|
|
|
void drainResidualPackets();
|
|
|
|
|
|
2015-01-15 16:55:50 +00:00
|
|
|
|
/// Получить адреса всех реплик в виде строки.
|
2015-01-15 12:09:26 +00:00
|
|
|
|
std::string dumpAddresses() const;
|
|
|
|
|
|
2015-01-15 16:55:50 +00:00
|
|
|
|
/// Возвращает количесто реплик.
|
|
|
|
|
size_t size() const
|
|
|
|
|
{
|
|
|
|
|
return replica_hash.size();
|
|
|
|
|
}
|
2015-01-15 15:05:03 +00:00
|
|
|
|
|
2015-01-15 16:55:50 +00:00
|
|
|
|
/// Отправить ко всем репликам всё содержимое внешних таблиц.
|
2015-01-15 15:05:03 +00:00
|
|
|
|
void sendExternalTablesData(std::vector<ExternalTablesData> & data);
|
|
|
|
|
|
2015-01-14 10:06:30 +00:00
|
|
|
|
private:
|
2015-01-15 16:55:50 +00:00
|
|
|
|
/// Описание реплики.
|
|
|
|
|
struct Replica
|
|
|
|
|
{
|
|
|
|
|
Replica(Connection * connection_) : connection(connection_) {}
|
|
|
|
|
|
|
|
|
|
/// Соединение к реплике
|
|
|
|
|
Connection * connection;
|
|
|
|
|
|
2015-01-15 18:06:51 +00:00
|
|
|
|
/// Номер следующего ожидаемого пакета.
|
2015-01-15 16:55:50 +00:00
|
|
|
|
int next_packet_number = 0;
|
|
|
|
|
|
|
|
|
|
/// Есть ли данные, которые можно прочитать?
|
|
|
|
|
bool can_read = false;
|
|
|
|
|
|
|
|
|
|
/// Является ли реплика валидной для чтения?
|
|
|
|
|
bool is_valid = true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/// Реплики хэшированные по id сокета
|
|
|
|
|
using ReplicaHash = std::unordered_map<int, Replica>;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
/// Выбрать реплику, на которой можно прочитать данные.
|
2015-01-15 18:03:59 +00:00
|
|
|
|
Replica & pickReplica();
|
2015-01-15 16:55:50 +00:00
|
|
|
|
|
|
|
|
|
/// Проверить, есть ли данные, которые можно прочитать на каких-нибудь репликах.
|
|
|
|
|
int waitForReadEvent();
|
2015-01-14 10:06:30 +00:00
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Settings * settings;
|
2015-01-15 16:55:50 +00:00
|
|
|
|
|
|
|
|
|
ReplicaHash replica_hash;
|
|
|
|
|
size_t valid_replicas_count;
|
|
|
|
|
|
2015-01-15 18:06:51 +00:00
|
|
|
|
/// Номер следующего ожидаемого пакета.
|
2015-01-14 13:16:03 +00:00
|
|
|
|
int next_packet_number = 0;
|
2015-01-14 10:06:30 +00:00
|
|
|
|
};
|
|
|
|
|
}
|