mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-26 17:41:59 +00:00
dbms: development [#CONV-2944].
This commit is contained in:
parent
4217baebdf
commit
65b3d8f761
@ -8,3 +8,4 @@
|
|||||||
#define DEFAULT_MAX_QUERY_SIZE 1048576
|
#define DEFAULT_MAX_QUERY_SIZE 1048576
|
||||||
#define SHOW_CHARS_ON_SYNTAX_ERROR 160L
|
#define SHOW_CHARS_ON_SYNTAX_ERROR 160L
|
||||||
#define DEFAULT_MAX_THREADS 8
|
#define DEFAULT_MAX_THREADS 8
|
||||||
|
#define DEFAULT_INTERACTIVE_DELAY 100000
|
||||||
|
@ -16,7 +16,7 @@ namespace Protocol
|
|||||||
Hello = 0, /// Имя, версия, ревизия.
|
Hello = 0, /// Имя, версия, ревизия.
|
||||||
Data = 1, /// Идентификатор запроса, признак последнего чанка, размер чанка, часть данных со сжатием или без.
|
Data = 1, /// Идентификатор запроса, признак последнего чанка, размер чанка, часть данных со сжатием или без.
|
||||||
Exception = 2, /// Исключение во время обработки запроса.
|
Exception = 2, /// Исключение во время обработки запроса.
|
||||||
Progress = 3, /// Прогресс выполнения запроса: строк считано, всего строк, байт считано, всего байт.
|
Progress = 3, /// Прогресс выполнения запроса: строк считано, байт считано.
|
||||||
Ok = 4, /// Запрос без возвращаемого результата успешно выполнен.
|
Ok = 4, /// Запрос без возвращаемого результата успешно выполнен.
|
||||||
Pong = 5, /// Ответ на Ping.
|
Pong = 5, /// Ответ на Ping.
|
||||||
};
|
};
|
||||||
|
@ -32,7 +32,7 @@ struct BlockStreamProfileInfo
|
|||||||
|
|
||||||
BlockStreamProfileInfo() : started(false), rows(0), blocks(0), bytes(0) {}
|
BlockStreamProfileInfo() : started(false), rows(0), blocks(0), bytes(0) {}
|
||||||
|
|
||||||
void update(Block & block);
|
void update(Block & block, size_t bytes_);
|
||||||
void print(std::ostream & ostr) const;
|
void print(std::ostream & ostr) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -59,9 +59,18 @@ public:
|
|||||||
typedef boost::function<bool()> IsCancelledCallback;
|
typedef boost::function<bool()> IsCancelledCallback;
|
||||||
void setIsCancelledCallback(IsCancelledCallback callback);
|
void setIsCancelledCallback(IsCancelledCallback callback);
|
||||||
|
|
||||||
|
/** Установить колбэк прогресса выполнения.
|
||||||
|
* Колбэк пробрасывается во все листовые источники и вызывается там после каждого блока.
|
||||||
|
* Функция принимает количество строк в последнем блоке, количество байт в последнем блоке.
|
||||||
|
* Следует иметь ввиду, что колбэк может вызываться из разных потоков.
|
||||||
|
*/
|
||||||
|
typedef boost::function<void(size_t, size_t)> ProgressCallback;
|
||||||
|
void setProgressCallback(ProgressCallback callback);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BlockStreamProfileInfo info;
|
BlockStreamProfileInfo info;
|
||||||
IsCancelledCallback is_cancelled_callback;
|
IsCancelledCallback is_cancelled_callback;
|
||||||
|
ProgressCallback progress_callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,14 @@ struct Settings
|
|||||||
size_t max_threads; /// Максимальное количество потоков выполнения запроса
|
size_t max_threads; /// Максимальное количество потоков выполнения запроса
|
||||||
size_t max_query_size; /// Какую часть запроса можно прочитать в оперативку для парсинга (оставшиеся данные для INSERT, если есть, считываются позже)
|
size_t max_query_size; /// Какую часть запроса можно прочитать в оперативку для парсинга (оставшиеся данные для INSERT, если есть, считываются позже)
|
||||||
bool asynchronous; /// Выполнять разные стадии конвейера выполнения запроса параллельно
|
bool asynchronous; /// Выполнять разные стадии конвейера выполнения запроса параллельно
|
||||||
|
size_t interactive_delay; /// Интервал в микросекундах для проверки, не запрошена ли остановка выполнения запроса, и отправки прогресса.
|
||||||
|
|
||||||
Settings() : max_block_size(DEFAULT_BLOCK_SIZE), max_threads(DEFAULT_MAX_THREADS), max_query_size(DEFAULT_MAX_QUERY_SIZE), asynchronous(true) {}
|
Settings() :
|
||||||
|
max_block_size(DEFAULT_BLOCK_SIZE),
|
||||||
|
max_threads(DEFAULT_MAX_THREADS),
|
||||||
|
max_query_size(DEFAULT_MAX_QUERY_SIZE),
|
||||||
|
asynchronous(true),
|
||||||
|
interactive_delay(DEFAULT_INTERACTIVE_DELAY) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ class Client : public Poco::Util::Application
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Client() : is_interactive(true), stdin_is_not_tty(false), socket(), in(socket), out(socket), query_id(0), compression(Protocol::Compression::Enable),
|
Client() : is_interactive(true), stdin_is_not_tty(false), socket(), in(socket), out(socket), query_id(0), compression(Protocol::Compression::Enable),
|
||||||
format_max_block_size(0), std_in(STDIN_FILENO), std_out(STDOUT_FILENO), received_rows(0) {}
|
format_max_block_size(0), std_in(STDIN_FILENO), std_out(STDOUT_FILENO), received_rows(0), written_progress_chars(0) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::tr1::unordered_set<String> StringSet;
|
typedef std::tr1::unordered_set<String> StringSet;
|
||||||
@ -173,6 +173,8 @@ private:
|
|||||||
ASTPtr parsed_query;
|
ASTPtr parsed_query;
|
||||||
bool expect_result; /// Запрос предполагает получение результата.
|
bool expect_result; /// Запрос предполагает получение результата.
|
||||||
|
|
||||||
|
size_t written_progress_chars;
|
||||||
|
|
||||||
|
|
||||||
void initialize(Poco::Util::Application & self)
|
void initialize(Poco::Util::Application & self)
|
||||||
{
|
{
|
||||||
@ -613,6 +615,10 @@ private:
|
|||||||
receiveOk();
|
receiveOk();
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
case Protocol::Server::Progress:
|
||||||
|
receiveProgress();
|
||||||
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw Exception("Unknown packet from server", ErrorCodes::UNKNOWN_PACKET_FROM_SERVER);
|
throw Exception("Unknown packet from server", ErrorCodes::UNKNOWN_PACKET_FROM_SERVER);
|
||||||
}
|
}
|
||||||
@ -636,6 +642,12 @@ private:
|
|||||||
*context.data_type_factory);
|
*context.data_type_factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (written_progress_chars)
|
||||||
|
{
|
||||||
|
std::cerr << std::string(written_progress_chars, '\b');
|
||||||
|
written_progress_chars = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// Прочитать из сети один блок и вывести его в консоль
|
/// Прочитать из сети один блок и вывести его в консоль
|
||||||
Block block = block_in->read();
|
Block block = block_in->read();
|
||||||
if (block)
|
if (block)
|
||||||
@ -687,6 +699,36 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void receiveProgress()
|
||||||
|
{
|
||||||
|
size_t rows = 0;
|
||||||
|
size_t bytes = 0;
|
||||||
|
readVarUInt(rows, in);
|
||||||
|
readVarUInt(bytes, in);
|
||||||
|
|
||||||
|
static size_t increment = 0;
|
||||||
|
static const char * indicators[8] =
|
||||||
|
{
|
||||||
|
"\033[1;30m.\033[0m",
|
||||||
|
"\033[1;31m.\033[0m",
|
||||||
|
"\033[1;32m.\033[0m",
|
||||||
|
"\033[1;33m.\033[0m",
|
||||||
|
"\033[1;34m.\033[0m",
|
||||||
|
"\033[1;35m.\033[0m",
|
||||||
|
"\033[1;36m.\033[0m",
|
||||||
|
"\033[1;37m.\033[0m",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (is_interactive)
|
||||||
|
{
|
||||||
|
//std::cout << "Progress: " << rows << " rows, " << bytes << " bytes." << std::endl;
|
||||||
|
std::cerr << indicators[increment % 8];
|
||||||
|
++increment;
|
||||||
|
++written_progress_chars;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void defineOptions(Poco::Util::OptionSet & options)
|
void defineOptions(Poco::Util::OptionSet & options)
|
||||||
{
|
{
|
||||||
Poco::Util::Application::defineOptions(options);
|
Poco::Util::Application::defineOptions(options);
|
||||||
|
@ -10,12 +10,11 @@ namespace DB
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
void BlockStreamProfileInfo::update(Block & block)
|
void BlockStreamProfileInfo::update(Block & block, size_t bytes_)
|
||||||
{
|
{
|
||||||
++blocks;
|
++blocks;
|
||||||
rows += block.rows();
|
rows += block.rows();
|
||||||
for (size_t i = 0; i < block.columns(); ++i)
|
bytes += bytes_;
|
||||||
bytes += block.getByPosition(i).column->byteSize();
|
|
||||||
|
|
||||||
if (column_names.empty())
|
if (column_names.empty())
|
||||||
column_names = block.dumpNames();
|
column_names = block.dumpNames();
|
||||||
@ -110,8 +109,15 @@ Block IProfilingBlockInputStream::read()
|
|||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
size_t bytes = 0;
|
||||||
|
for (size_t i = 0; i < res.columns(); ++i)
|
||||||
|
bytes += res.getByPosition(i).column->byteSize();
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
info.update(res);
|
info.update(res, bytes);
|
||||||
|
|
||||||
|
if (progress_callback)
|
||||||
|
progress_callback(res.rows(), bytes);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -125,12 +131,19 @@ const BlockStreamProfileInfo & IProfilingBlockInputStream::getInfo() const
|
|||||||
|
|
||||||
void IProfilingBlockInputStream::setIsCancelledCallback(IsCancelledCallback callback)
|
void IProfilingBlockInputStream::setIsCancelledCallback(IsCancelledCallback callback)
|
||||||
{
|
{
|
||||||
is_cancelled_callback = callback;
|
|
||||||
|
|
||||||
BlockInputStreams leaves = getLeaves();
|
BlockInputStreams leaves = getLeaves();
|
||||||
for (BlockInputStreams::iterator it = leaves.begin(); it != leaves.end(); ++it)
|
for (BlockInputStreams::iterator it = leaves.begin(); it != leaves.end(); ++it)
|
||||||
if (IProfilingBlockInputStream * leaf = dynamic_cast<IProfilingBlockInputStream *>(&**it))
|
if (IProfilingBlockInputStream * leaf = dynamic_cast<IProfilingBlockInputStream *>(&**it))
|
||||||
leaf->setIsCancelledCallback(callback);
|
leaf->is_cancelled_callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IProfilingBlockInputStream::setProgressCallback(ProgressCallback callback)
|
||||||
|
{
|
||||||
|
BlockInputStreams leaves = getLeaves();
|
||||||
|
for (BlockInputStreams::iterator it = leaves.begin(); it != leaves.end(); ++it)
|
||||||
|
if (IProfilingBlockInputStream * leaf = dynamic_cast<IProfilingBlockInputStream *>(&**it))
|
||||||
|
leaf->progress_callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,6 +84,7 @@ int Server::main(const std::vector<std::string> & args)
|
|||||||
global_context.settings.max_block_size = config.getInt("max_block_size", global_context.settings.max_block_size);
|
global_context.settings.max_block_size = config.getInt("max_block_size", global_context.settings.max_block_size);
|
||||||
global_context.settings.max_query_size = config.getInt("max_query_size", global_context.settings.max_query_size);
|
global_context.settings.max_query_size = config.getInt("max_query_size", global_context.settings.max_query_size);
|
||||||
global_context.settings.max_threads = config.getInt("max_threads", global_context.settings.max_threads);
|
global_context.settings.max_threads = config.getInt("max_threads", global_context.settings.max_threads);
|
||||||
|
global_context.settings.interactive_delay = config.getInt("interactive_delay", global_context.settings.interactive_delay);
|
||||||
|
|
||||||
Poco::Net::ServerSocket http_socket(Poco::Net::SocketAddress("[::]:" + config.getString("http_port")));
|
Poco::Net::ServerSocket http_socket(Poco::Net::SocketAddress("[::]:" + config.getString("http_port")));
|
||||||
Poco::Net::ServerSocket tcp_socket(Poco::Net::SocketAddress("[::]:" + config.getString("tcp_port")));
|
Poco::Net::ServerSocket tcp_socket(Poco::Net::SocketAddress("[::]:" + config.getString("tcp_port")));
|
||||||
|
@ -8,8 +8,6 @@
|
|||||||
|
|
||||||
#include <DB/Core/ErrorCodes.h>
|
#include <DB/Core/ErrorCodes.h>
|
||||||
|
|
||||||
#include <DB/IO/ReadBufferFromPocoSocket.h>
|
|
||||||
#include <DB/IO/WriteBufferFromPocoSocket.h>
|
|
||||||
#include <DB/IO/CompressedReadBuffer.h>
|
#include <DB/IO/CompressedReadBuffer.h>
|
||||||
#include <DB/IO/CompressedWriteBuffer.h>
|
#include <DB/IO/CompressedWriteBuffer.h>
|
||||||
#include <DB/IO/copyData.h>
|
#include <DB/IO/copyData.h>
|
||||||
@ -43,13 +41,14 @@ void TCPHandler::runImpl()
|
|||||||
/// Пакет с запросом.
|
/// Пакет с запросом.
|
||||||
receivePacket(in, out);
|
receivePacket(in, out);
|
||||||
|
|
||||||
|
after_check_cancelled.restart();
|
||||||
|
after_send_progress.restart();
|
||||||
|
|
||||||
LOG_DEBUG(log, "Query ID: " << state.query_id);
|
LOG_DEBUG(log, "Query ID: " << state.query_id);
|
||||||
LOG_DEBUG(log, "Query: " << state.query);
|
LOG_DEBUG(log, "Query: " << state.query);
|
||||||
LOG_DEBUG(log, "In format: " << state.in_format);
|
LOG_DEBUG(log, "In format: " << state.in_format);
|
||||||
LOG_DEBUG(log, "Out format: " << state.out_format);
|
LOG_DEBUG(log, "Out format: " << state.out_format);
|
||||||
|
|
||||||
state.exception = NULL;
|
|
||||||
|
|
||||||
/// Читаем из сети данные для INSERT-а, если надо, и вставляем их.
|
/// Читаем из сети данные для INSERT-а, если надо, и вставляем их.
|
||||||
if (state.io.out)
|
if (state.io.out)
|
||||||
{
|
{
|
||||||
@ -61,7 +60,10 @@ void TCPHandler::runImpl()
|
|||||||
if (state.io.in)
|
if (state.io.in)
|
||||||
{
|
{
|
||||||
if (IProfilingBlockInputStream * profiling_in = dynamic_cast<IProfilingBlockInputStream *>(&*state.io.in))
|
if (IProfilingBlockInputStream * profiling_in = dynamic_cast<IProfilingBlockInputStream *>(&*state.io.in))
|
||||||
|
{
|
||||||
profiling_in->setIsCancelledCallback(boost::bind(&TCPHandler::isQueryCancelled, this, boost::ref(in)));
|
profiling_in->setIsCancelledCallback(boost::bind(&TCPHandler::isQueryCancelled, this, boost::ref(in)));
|
||||||
|
profiling_in->setProgressCallback(boost::bind(&TCPHandler::sendProgress, this, boost::ref(out), 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
while (sendData(out, out_for_chunks))
|
while (sendData(out, out_for_chunks))
|
||||||
;
|
;
|
||||||
@ -197,12 +199,17 @@ bool TCPHandler::receiveData(ReadBuffer & in)
|
|||||||
|
|
||||||
bool TCPHandler::isQueryCancelled(ReadBufferFromPocoSocket & in)
|
bool TCPHandler::isQueryCancelled(ReadBufferFromPocoSocket & in)
|
||||||
{
|
{
|
||||||
|
Poco::ScopedLock<Poco::FastMutex> lock(is_cancelled_mutex);
|
||||||
|
|
||||||
|
if (after_check_cancelled.elapsed() / 1000 < state.context.settings.interactive_delay)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
after_check_cancelled.restart();
|
||||||
|
|
||||||
/// Во время выполнения запроса, единственный пакет, который может прийти от клиента - это остановка выполнения запроса.
|
/// Во время выполнения запроса, единственный пакет, который может прийти от клиента - это остановка выполнения запроса.
|
||||||
std::cerr << "checking cancelled" << std::endl;
|
std::cerr << "checking cancelled" << std::endl;
|
||||||
if (in.poll(0))
|
if (in.poll(0))
|
||||||
{
|
{
|
||||||
Poco::ScopedLock<Poco::FastMutex> lock(is_cancelled_mutex);
|
|
||||||
|
|
||||||
std::cerr << "checking cancelled; socket has data" << std::endl;
|
std::cerr << "checking cancelled; socket has data" << std::endl;
|
||||||
|
|
||||||
UInt64 packet_type = 0;
|
UInt64 packet_type = 0;
|
||||||
@ -229,6 +236,8 @@ bool TCPHandler::sendData(WriteBuffer & out, WriteBuffer & out_for_chunks)
|
|||||||
/// Получить один блок результата выполнения запроса из state.io.in.
|
/// Получить один блок результата выполнения запроса из state.io.in.
|
||||||
Block block = state.io.in->read();
|
Block block = state.io.in->read();
|
||||||
|
|
||||||
|
Poco::ScopedLock<Poco::FastMutex> lock(send_mutex);
|
||||||
|
|
||||||
writeVarUInt(Protocol::Server::Data, out);
|
writeVarUInt(Protocol::Server::Data, out);
|
||||||
out.next();
|
out.next();
|
||||||
|
|
||||||
@ -260,12 +269,15 @@ bool TCPHandler::sendData(WriteBuffer & out, WriteBuffer & out_for_chunks)
|
|||||||
{
|
{
|
||||||
dynamic_cast<ChunkedWriteBuffer &>(*state.chunked_out).finish();
|
dynamic_cast<ChunkedWriteBuffer &>(*state.chunked_out).finish();
|
||||||
out_for_chunks.next();
|
out_for_chunks.next();
|
||||||
|
state.sent_all_data = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCPHandler::sendException(WriteBuffer & out)
|
void TCPHandler::sendException(WriteBuffer & out)
|
||||||
{
|
{
|
||||||
|
Poco::ScopedLock<Poco::FastMutex> lock(send_mutex);
|
||||||
|
|
||||||
writeVarUInt(Protocol::Server::Exception, out);
|
writeVarUInt(Protocol::Server::Exception, out);
|
||||||
writeException(*state.exception, out);
|
writeException(*state.exception, out);
|
||||||
out.next();
|
out.next();
|
||||||
@ -273,13 +285,29 @@ void TCPHandler::sendException(WriteBuffer & out)
|
|||||||
|
|
||||||
void TCPHandler::sendOk(WriteBuffer & out)
|
void TCPHandler::sendOk(WriteBuffer & out)
|
||||||
{
|
{
|
||||||
|
Poco::ScopedLock<Poco::FastMutex> lock(send_mutex);
|
||||||
|
|
||||||
writeVarUInt(Protocol::Server::Ok, out);
|
writeVarUInt(Protocol::Server::Ok, out);
|
||||||
out.next();
|
out.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCPHandler::sendProgress(WriteBuffer & out)
|
void TCPHandler::sendProgress(WriteBuffer & out, size_t rows, size_t bytes)
|
||||||
{
|
{
|
||||||
/// TODO
|
Poco::ScopedLock<Poco::FastMutex> lock(send_mutex);
|
||||||
|
|
||||||
|
/// Не будем отправлять прогресс после того, как отправлены все данные.
|
||||||
|
if (state.sent_all_data)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (after_send_progress.elapsed() / 1000 < state.context.settings.interactive_delay)
|
||||||
|
return;
|
||||||
|
|
||||||
|
after_send_progress.restart();
|
||||||
|
|
||||||
|
writeVarUInt(Protocol::Server::Progress, out);
|
||||||
|
writeVarUInt(rows, out);
|
||||||
|
writeVarUInt(bytes, out);
|
||||||
|
out.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,9 +8,12 @@
|
|||||||
#include <DB/IO/ReadHelpers.h>
|
#include <DB/IO/ReadHelpers.h>
|
||||||
#include <DB/IO/WriteHelpers.h>
|
#include <DB/IO/WriteHelpers.h>
|
||||||
#include <DB/IO/ReadBufferFromPocoSocket.h>
|
#include <DB/IO/ReadBufferFromPocoSocket.h>
|
||||||
|
#include <DB/IO/WriteBufferFromPocoSocket.h>
|
||||||
|
|
||||||
#include <DB/DataStreams/BlockIO.h>
|
#include <DB/DataStreams/BlockIO.h>
|
||||||
|
|
||||||
|
#include <statdaemons/Stopwatch.h>
|
||||||
|
|
||||||
#include "Server.h"
|
#include "Server.h"
|
||||||
|
|
||||||
|
|
||||||
@ -51,8 +54,10 @@ struct QueryState
|
|||||||
*/
|
*/
|
||||||
SharedPtr<Exception> exception;
|
SharedPtr<Exception> exception;
|
||||||
|
|
||||||
|
/// Данные были отправлены.
|
||||||
|
bool sent_all_data;
|
||||||
|
|
||||||
QueryState() : query_id(0), stage(QueryProcessingStage::Complete), compression(Protocol::Compression::Disable) {}
|
QueryState() : query_id(0), stage(QueryProcessingStage::Complete), compression(Protocol::Compression::Disable), sent_all_data(false) {}
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
@ -86,6 +91,12 @@ private:
|
|||||||
QueryState state;
|
QueryState state;
|
||||||
|
|
||||||
Poco::FastMutex is_cancelled_mutex;
|
Poco::FastMutex is_cancelled_mutex;
|
||||||
|
/// Для сериализации пакетов "данные" и "прогресс" (пакет типа "прогресс" может отправляться из другого потока).
|
||||||
|
Poco::FastMutex send_mutex;
|
||||||
|
|
||||||
|
/// Время после последней проверки остановки запроса и отправки прогресса.
|
||||||
|
Stopwatch after_check_cancelled;
|
||||||
|
Stopwatch after_send_progress;
|
||||||
|
|
||||||
|
|
||||||
void runImpl();
|
void runImpl();
|
||||||
@ -93,7 +104,7 @@ private:
|
|||||||
void sendHello(WriteBuffer & out);
|
void sendHello(WriteBuffer & out);
|
||||||
bool sendData(WriteBuffer & out, WriteBuffer & out_for_chunks);
|
bool sendData(WriteBuffer & out, WriteBuffer & out_for_chunks);
|
||||||
void sendException(WriteBuffer & out);
|
void sendException(WriteBuffer & out);
|
||||||
void sendProgress(WriteBuffer & out);
|
void sendProgress(WriteBuffer & out, size_t rows, size_t bytes);
|
||||||
void sendOk(WriteBuffer & out);
|
void sendOk(WriteBuffer & out);
|
||||||
|
|
||||||
bool receivePacket(ReadBuffer & in, WriteBuffer & out);
|
bool receivePacket(ReadBuffer & in, WriteBuffer & out);
|
||||||
|
Loading…
Reference in New Issue
Block a user