mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-04 21:42:39 +00:00
Merge pull request #71901 from jkartseva/fix-infile-interactive-metrics
Fix data race between progress indicator and progress table in clickhouse-client
This commit is contained in:
commit
3c0f299148
@ -68,15 +68,16 @@
|
|||||||
#include <Access/AccessControl.h>
|
#include <Access/AccessControl.h>
|
||||||
#include <Storages/ColumnsDescription.h>
|
#include <Storages/ColumnsDescription.h>
|
||||||
|
|
||||||
#include <boost/algorithm/string/case_conv.hpp>
|
|
||||||
#include <boost/algorithm/string/replace.hpp>
|
|
||||||
#include <iostream>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <iostream>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <boost/algorithm/string/case_conv.hpp>
|
||||||
|
#include <boost/algorithm/string/replace.hpp>
|
||||||
|
|
||||||
#include <Common/config_version.h>
|
#include <Common/config_version.h>
|
||||||
#include <base/find_symbols.h>
|
#include <base/find_symbols.h>
|
||||||
@ -441,9 +442,15 @@ void ClientBase::onData(Block & block, ASTPtr parsed_query)
|
|||||||
|
|
||||||
/// If results are written INTO OUTFILE, we can avoid clearing progress to avoid flicker.
|
/// If results are written INTO OUTFILE, we can avoid clearing progress to avoid flicker.
|
||||||
if (need_render_progress && tty_buf && (!select_into_file || select_into_file_and_stdout))
|
if (need_render_progress && tty_buf && (!select_into_file || select_into_file_and_stdout))
|
||||||
progress_indication.clearProgressOutput(*tty_buf);
|
{
|
||||||
|
std::unique_lock lock(tty_mutex);
|
||||||
|
progress_indication.clearProgressOutput(*tty_buf, lock);
|
||||||
|
}
|
||||||
if (need_render_progress_table && tty_buf && (!select_into_file || select_into_file_and_stdout))
|
if (need_render_progress_table && tty_buf && (!select_into_file || select_into_file_and_stdout))
|
||||||
progress_table.clearTableOutput(*tty_buf);
|
{
|
||||||
|
std::unique_lock lock(tty_mutex);
|
||||||
|
progress_table.clearTableOutput(*tty_buf, lock);
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -464,13 +471,15 @@ void ClientBase::onData(Block & block, ASTPtr parsed_query)
|
|||||||
{
|
{
|
||||||
if (select_into_file && !select_into_file_and_stdout)
|
if (select_into_file && !select_into_file_and_stdout)
|
||||||
error_stream << "\r";
|
error_stream << "\r";
|
||||||
progress_indication.writeProgress(*tty_buf);
|
std::unique_lock lock(tty_mutex);
|
||||||
|
progress_indication.writeProgress(*tty_buf, lock);
|
||||||
}
|
}
|
||||||
if (need_render_progress_table && tty_buf && !cancelled)
|
if (need_render_progress_table && tty_buf && !cancelled)
|
||||||
{
|
{
|
||||||
if (!need_render_progress && select_into_file && !select_into_file_and_stdout)
|
if (!need_render_progress && select_into_file && !select_into_file_and_stdout)
|
||||||
error_stream << "\r";
|
error_stream << "\r";
|
||||||
progress_table.writeTable(*tty_buf, progress_table_toggle_on.load(), progress_table_toggle_enabled);
|
std::unique_lock lock(tty_mutex);
|
||||||
|
progress_table.writeTable(*tty_buf, lock, progress_table_toggle_on.load(), progress_table_toggle_enabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -479,9 +488,15 @@ void ClientBase::onLogData(Block & block)
|
|||||||
{
|
{
|
||||||
initLogsOutputStream();
|
initLogsOutputStream();
|
||||||
if (need_render_progress && tty_buf)
|
if (need_render_progress && tty_buf)
|
||||||
progress_indication.clearProgressOutput(*tty_buf);
|
{
|
||||||
|
std::unique_lock lock(tty_mutex);
|
||||||
|
progress_indication.clearProgressOutput(*tty_buf, lock);
|
||||||
|
}
|
||||||
if (need_render_progress_table && tty_buf)
|
if (need_render_progress_table && tty_buf)
|
||||||
progress_table.clearTableOutput(*tty_buf);
|
{
|
||||||
|
std::unique_lock lock(tty_mutex);
|
||||||
|
progress_table.clearTableOutput(*tty_buf, lock);
|
||||||
|
}
|
||||||
logs_out_stream->writeLogs(block);
|
logs_out_stream->writeLogs(block);
|
||||||
logs_out_stream->flush();
|
logs_out_stream->flush();
|
||||||
}
|
}
|
||||||
@ -1151,34 +1166,8 @@ void ClientBase::receiveResult(ASTPtr parsed_query, Int32 signals_before_stop, b
|
|||||||
|
|
||||||
std::exception_ptr local_format_error;
|
std::exception_ptr local_format_error;
|
||||||
|
|
||||||
if (keystroke_interceptor)
|
startKeystrokeInterceptorIfExists();
|
||||||
{
|
SCOPE_EXIT({ stopKeystrokeInterceptorIfExists(); });
|
||||||
progress_table_toggle_on = false;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
keystroke_interceptor->startIntercept();
|
|
||||||
}
|
|
||||||
catch (const DB::Exception &)
|
|
||||||
{
|
|
||||||
error_stream << getCurrentExceptionMessage(false);
|
|
||||||
keystroke_interceptor.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SCOPE_EXIT({
|
|
||||||
if (keystroke_interceptor)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
keystroke_interceptor->stopIntercept();
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
error_stream << getCurrentExceptionMessage(false);
|
|
||||||
keystroke_interceptor.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
@ -1318,7 +1307,10 @@ void ClientBase::onProgress(const Progress & value)
|
|||||||
output_format->onProgress(value);
|
output_format->onProgress(value);
|
||||||
|
|
||||||
if (need_render_progress && tty_buf)
|
if (need_render_progress && tty_buf)
|
||||||
progress_indication.writeProgress(*tty_buf);
|
{
|
||||||
|
std::unique_lock lock(tty_mutex);
|
||||||
|
progress_indication.writeProgress(*tty_buf, lock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientBase::onTimezoneUpdate(const String & tz)
|
void ClientBase::onTimezoneUpdate(const String & tz)
|
||||||
@ -1330,9 +1322,15 @@ void ClientBase::onTimezoneUpdate(const String & tz)
|
|||||||
void ClientBase::onEndOfStream()
|
void ClientBase::onEndOfStream()
|
||||||
{
|
{
|
||||||
if (need_render_progress && tty_buf)
|
if (need_render_progress && tty_buf)
|
||||||
progress_indication.clearProgressOutput(*tty_buf);
|
{
|
||||||
|
std::unique_lock lock(tty_mutex);
|
||||||
|
progress_indication.clearProgressOutput(*tty_buf, lock);
|
||||||
|
}
|
||||||
if (need_render_progress_table && tty_buf)
|
if (need_render_progress_table && tty_buf)
|
||||||
progress_table.clearTableOutput(*tty_buf);
|
{
|
||||||
|
std::unique_lock lock(tty_mutex);
|
||||||
|
progress_table.clearTableOutput(*tty_buf, lock);
|
||||||
|
}
|
||||||
|
|
||||||
if (output_format)
|
if (output_format)
|
||||||
{
|
{
|
||||||
@ -1414,11 +1412,15 @@ void ClientBase::onProfileEvents(Block & block)
|
|||||||
progress_table.updateTable(block);
|
progress_table.updateTable(block);
|
||||||
|
|
||||||
if (need_render_progress && tty_buf)
|
if (need_render_progress && tty_buf)
|
||||||
progress_indication.writeProgress(*tty_buf);
|
{
|
||||||
|
std::unique_lock lock(tty_mutex);
|
||||||
|
progress_indication.writeProgress(*tty_buf, lock);
|
||||||
|
}
|
||||||
if (need_render_progress_table && tty_buf && !cancelled)
|
if (need_render_progress_table && tty_buf && !cancelled)
|
||||||
{
|
{
|
||||||
bool toggle_enabled = getClientConfiguration().getBool("enable-progress-table-toggle", true);
|
bool toggle_enabled = getClientConfiguration().getBool("enable-progress-table-toggle", true);
|
||||||
progress_table.writeTable(*tty_buf, progress_table_toggle_on.load(), toggle_enabled);
|
std::unique_lock lock(tty_mutex);
|
||||||
|
progress_table.writeTable(*tty_buf, lock, progress_table_toggle_on.load(), toggle_enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (profile_events.print)
|
if (profile_events.print)
|
||||||
@ -1429,9 +1431,15 @@ void ClientBase::onProfileEvents(Block & block)
|
|||||||
profile_events.watch.restart();
|
profile_events.watch.restart();
|
||||||
initLogsOutputStream();
|
initLogsOutputStream();
|
||||||
if (need_render_progress && tty_buf)
|
if (need_render_progress && tty_buf)
|
||||||
progress_indication.clearProgressOutput(*tty_buf);
|
{
|
||||||
|
std::unique_lock lock(tty_mutex);
|
||||||
|
progress_indication.clearProgressOutput(*tty_buf, lock);
|
||||||
|
}
|
||||||
if (need_render_progress_table && tty_buf)
|
if (need_render_progress_table && tty_buf)
|
||||||
progress_table.clearTableOutput(*tty_buf);
|
{
|
||||||
|
std::unique_lock lock(tty_mutex);
|
||||||
|
progress_table.clearTableOutput(*tty_buf, lock);
|
||||||
|
}
|
||||||
logs_out_stream->writeProfileEvents(block);
|
logs_out_stream->writeProfileEvents(block);
|
||||||
logs_out_stream->flush();
|
logs_out_stream->flush();
|
||||||
|
|
||||||
@ -1450,7 +1458,10 @@ void ClientBase::onProfileEvents(Block & block)
|
|||||||
void ClientBase::resetOutput()
|
void ClientBase::resetOutput()
|
||||||
{
|
{
|
||||||
if (need_render_progress_table && tty_buf)
|
if (need_render_progress_table && tty_buf)
|
||||||
progress_table.clearTableOutput(*tty_buf);
|
{
|
||||||
|
std::unique_lock lock(tty_mutex);
|
||||||
|
progress_table.clearTableOutput(*tty_buf, lock);
|
||||||
|
}
|
||||||
|
|
||||||
/// Order is important: format, compression, file
|
/// Order is important: format, compression, file
|
||||||
|
|
||||||
@ -1619,6 +1630,9 @@ void ClientBase::processInsertQuery(const String & query_to_execute, ASTPtr pars
|
|||||||
if (send_external_tables)
|
if (send_external_tables)
|
||||||
sendExternalTables(parsed_query);
|
sendExternalTables(parsed_query);
|
||||||
|
|
||||||
|
startKeystrokeInterceptorIfExists();
|
||||||
|
SCOPE_EXIT({ stopKeystrokeInterceptorIfExists(); });
|
||||||
|
|
||||||
/// Receive description of table structure.
|
/// Receive description of table structure.
|
||||||
Block sample;
|
Block sample;
|
||||||
ColumnsDescription columns_description;
|
ColumnsDescription columns_description;
|
||||||
@ -1665,7 +1679,7 @@ void ClientBase::sendData(Block & sample, const ColumnsDescription & columns_des
|
|||||||
|
|
||||||
/// Set callback to be called on file progress.
|
/// Set callback to be called on file progress.
|
||||||
if (tty_buf)
|
if (tty_buf)
|
||||||
progress_indication.setFileProgressCallback(client_context, *tty_buf);
|
progress_indication.setFileProgressCallback(client_context, *tty_buf, tty_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If data fetched from file (maybe compressed file)
|
/// If data fetched from file (maybe compressed file)
|
||||||
@ -1947,9 +1961,15 @@ void ClientBase::cancelQuery()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (need_render_progress && tty_buf)
|
if (need_render_progress && tty_buf)
|
||||||
progress_indication.clearProgressOutput(*tty_buf);
|
{
|
||||||
|
std::unique_lock lock(tty_mutex);
|
||||||
|
progress_indication.clearProgressOutput(*tty_buf, lock);
|
||||||
|
}
|
||||||
if (need_render_progress_table && tty_buf)
|
if (need_render_progress_table && tty_buf)
|
||||||
progress_table.clearTableOutput(*tty_buf);
|
{
|
||||||
|
std::unique_lock lock(tty_mutex);
|
||||||
|
progress_table.clearTableOutput(*tty_buf, lock);
|
||||||
|
}
|
||||||
|
|
||||||
if (is_interactive)
|
if (is_interactive)
|
||||||
output_stream << "Cancelling query." << std::endl;
|
output_stream << "Cancelling query." << std::endl;
|
||||||
@ -2112,9 +2132,15 @@ void ClientBase::processParsedSingleQuery(const String & full_query, const Strin
|
|||||||
{
|
{
|
||||||
initLogsOutputStream();
|
initLogsOutputStream();
|
||||||
if (need_render_progress && tty_buf)
|
if (need_render_progress && tty_buf)
|
||||||
progress_indication.clearProgressOutput(*tty_buf);
|
{
|
||||||
|
std::unique_lock lock(tty_mutex);
|
||||||
|
progress_indication.clearProgressOutput(*tty_buf, lock);
|
||||||
|
}
|
||||||
if (need_render_progress_table && tty_buf)
|
if (need_render_progress_table && tty_buf)
|
||||||
progress_table.clearTableOutput(*tty_buf);
|
{
|
||||||
|
std::unique_lock lock(tty_mutex);
|
||||||
|
progress_table.clearTableOutput(*tty_buf, lock);
|
||||||
|
}
|
||||||
logs_out_stream->writeProfileEvents(profile_events.last_block);
|
logs_out_stream->writeProfileEvents(profile_events.last_block);
|
||||||
logs_out_stream->flush();
|
logs_out_stream->flush();
|
||||||
|
|
||||||
@ -2613,6 +2639,39 @@ bool ClientBase::addMergeTreeSettings(ASTCreateQuery & ast_create)
|
|||||||
return added_new_setting;
|
return added_new_setting;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClientBase::startKeystrokeInterceptorIfExists()
|
||||||
|
{
|
||||||
|
if (keystroke_interceptor)
|
||||||
|
{
|
||||||
|
progress_table_toggle_on = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
keystroke_interceptor->startIntercept();
|
||||||
|
}
|
||||||
|
catch (const DB::Exception &)
|
||||||
|
{
|
||||||
|
error_stream << getCurrentExceptionMessage(false);
|
||||||
|
keystroke_interceptor.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientBase::stopKeystrokeInterceptorIfExists()
|
||||||
|
{
|
||||||
|
if (keystroke_interceptor)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
keystroke_interceptor->stopIntercept();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
error_stream << getCurrentExceptionMessage(false);
|
||||||
|
keystroke_interceptor.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ClientBase::runInteractive()
|
void ClientBase::runInteractive()
|
||||||
{
|
{
|
||||||
if (getClientConfiguration().has("query_id"))
|
if (getClientConfiguration().has("query_id"))
|
||||||
|
@ -208,6 +208,9 @@ private:
|
|||||||
void initQueryIdFormats();
|
void initQueryIdFormats();
|
||||||
bool addMergeTreeSettings(ASTCreateQuery & ast_create);
|
bool addMergeTreeSettings(ASTCreateQuery & ast_create);
|
||||||
|
|
||||||
|
void startKeystrokeInterceptorIfExists();
|
||||||
|
void stopKeystrokeInterceptorIfExists();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
class QueryInterruptHandler : private boost::noncopyable
|
class QueryInterruptHandler : private boost::noncopyable
|
||||||
@ -325,6 +328,7 @@ protected:
|
|||||||
/// /dev/tty if accessible or std::cerr - for progress bar.
|
/// /dev/tty if accessible or std::cerr - for progress bar.
|
||||||
/// We prefer to output progress bar directly to tty to allow user to redirect stdout and stderr and still get the progress indication.
|
/// We prefer to output progress bar directly to tty to allow user to redirect stdout and stderr and still get the progress indication.
|
||||||
std::unique_ptr<WriteBufferFromFileDescriptor> tty_buf;
|
std::unique_ptr<WriteBufferFromFileDescriptor> tty_buf;
|
||||||
|
std::mutex tty_mutex;
|
||||||
|
|
||||||
String home_path;
|
String home_path;
|
||||||
String history_file; /// Path to a file containing command history.
|
String history_file; /// Path to a file containing command history.
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <Common/formatReadable.h>
|
#include <Common/formatReadable.h>
|
||||||
|
|
||||||
#include <format>
|
#include <format>
|
||||||
|
#include <mutex>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
@ -192,7 +193,8 @@ void writeWithWidthStrict(Out & out, std::string_view s, size_t width)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProgressTable::writeTable(WriteBufferFromFileDescriptor & message, bool show_table, bool toggle_enabled)
|
void ProgressTable::writeTable(
|
||||||
|
WriteBufferFromFileDescriptor & message, std::unique_lock<std::mutex> &, bool show_table, bool toggle_enabled)
|
||||||
{
|
{
|
||||||
std::lock_guard lock{mutex};
|
std::lock_guard lock{mutex};
|
||||||
if (!show_table && toggle_enabled)
|
if (!show_table && toggle_enabled)
|
||||||
@ -360,7 +362,7 @@ void ProgressTable::updateTable(const Block & block)
|
|||||||
written_first_block = true;
|
written_first_block = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProgressTable::clearTableOutput(WriteBufferFromFileDescriptor & message)
|
void ProgressTable::clearTableOutput(WriteBufferFromFileDescriptor & message, std::unique_lock<std::mutex> &)
|
||||||
{
|
{
|
||||||
message << "\r" << CLEAR_TO_END_OF_SCREEN << SHOW_CURSOR;
|
message << "\r" << CLEAR_TO_END_OF_SCREEN << SHOW_CURSOR;
|
||||||
message.next();
|
message.next();
|
||||||
|
@ -27,8 +27,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Write progress table with metrics.
|
/// Write progress table with metrics.
|
||||||
void writeTable(WriteBufferFromFileDescriptor & message, bool show_table, bool toggle_enabled);
|
void writeTable(WriteBufferFromFileDescriptor & message, std::unique_lock<std::mutex> & message_lock,
|
||||||
void clearTableOutput(WriteBufferFromFileDescriptor & message);
|
bool show_table, bool toggle_enabled);
|
||||||
|
void clearTableOutput(WriteBufferFromFileDescriptor & message, std::unique_lock<std::mutex> & message_lock);
|
||||||
void writeFinalTable();
|
void writeFinalTable();
|
||||||
|
|
||||||
/// Update the metric values. They can be updated from:
|
/// Update the metric values. They can be updated from:
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <mutex>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@ -49,12 +50,13 @@ void ProgressIndication::resetProgress()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProgressIndication::setFileProgressCallback(ContextMutablePtr context, WriteBufferFromFileDescriptor & message)
|
void ProgressIndication::setFileProgressCallback(ContextMutablePtr context, WriteBufferFromFileDescriptor & message, std::mutex & message_mutex)
|
||||||
{
|
{
|
||||||
context->setFileProgressCallback([&](const FileProgress & file_progress)
|
context->setFileProgressCallback([&](const FileProgress & file_progress)
|
||||||
{
|
{
|
||||||
progress.incrementPiecewiseAtomically(Progress(file_progress));
|
progress.incrementPiecewiseAtomically(Progress(file_progress));
|
||||||
writeProgress(message);
|
std::unique_lock message_lock(message_mutex);
|
||||||
|
writeProgress(message, message_lock);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +115,7 @@ void ProgressIndication::writeFinalProgress()
|
|||||||
output_stream << "\nPeak memory usage: " << formatReadableSizeWithBinarySuffix(peak_memory_usage) << ".";
|
output_stream << "\nPeak memory usage: " << formatReadableSizeWithBinarySuffix(peak_memory_usage) << ".";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProgressIndication::writeProgress(WriteBufferFromFileDescriptor & message)
|
void ProgressIndication::writeProgress(WriteBufferFromFileDescriptor & message, std::unique_lock<std::mutex> &)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(progress_mutex);
|
std::lock_guard lock(progress_mutex);
|
||||||
|
|
||||||
@ -274,7 +276,7 @@ void ProgressIndication::writeProgress(WriteBufferFromFileDescriptor & message)
|
|||||||
message.next();
|
message.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProgressIndication::clearProgressOutput(WriteBufferFromFileDescriptor & message)
|
void ProgressIndication::clearProgressOutput(WriteBufferFromFileDescriptor & message, std::unique_lock<std::mutex> &)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(progress_mutex);
|
std::lock_guard lock(progress_mutex);
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <queue>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
@ -47,8 +48,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Write progress bar.
|
/// Write progress bar.
|
||||||
void writeProgress(WriteBufferFromFileDescriptor & message);
|
void writeProgress(WriteBufferFromFileDescriptor & message, std::unique_lock<std::mutex> & message_lock);
|
||||||
void clearProgressOutput(WriteBufferFromFileDescriptor & message);
|
void clearProgressOutput(WriteBufferFromFileDescriptor & message, std::unique_lock<std::mutex> & message_lock);
|
||||||
|
|
||||||
/// Write summary.
|
/// Write summary.
|
||||||
void writeFinalProgress();
|
void writeFinalProgress();
|
||||||
@ -67,7 +68,7 @@ public:
|
|||||||
/// In some cases there is a need to update progress value, when there is no access to progress_inidcation object.
|
/// In some cases there is a need to update progress value, when there is no access to progress_inidcation object.
|
||||||
/// In this case it is added via context.
|
/// In this case it is added via context.
|
||||||
/// `write_progress_on_update` is needed to write progress for loading files data via pipe in non-interactive mode.
|
/// `write_progress_on_update` is needed to write progress for loading files data via pipe in non-interactive mode.
|
||||||
void setFileProgressCallback(ContextMutablePtr context, WriteBufferFromFileDescriptor & message);
|
void setFileProgressCallback(ContextMutablePtr context, WriteBufferFromFileDescriptor & message, std::mutex & message_mutex);
|
||||||
|
|
||||||
/// How much seconds passed since query execution start.
|
/// How much seconds passed since query execution start.
|
||||||
double elapsedSeconds() const { return getElapsedNanoseconds() / 1e9; }
|
double elapsedSeconds() const { return getElapsedNanoseconds() / 1e9; }
|
||||||
|
Loading…
Reference in New Issue
Block a user