ClickHouse/src/Common/ProgressIndication.h

111 lines
3.5 KiB
C++
Raw Normal View History

#pragma once
2021-09-15 15:45:43 +00:00
#include <unordered_map>
2021-09-14 11:06:00 +00:00
#include <unordered_set>
#include <mutex>
#include <IO/Progress.h>
#include <Interpreters/Context.h>
2021-09-14 11:06:00 +00:00
#include <base/types.h>
#include <Common/Stopwatch.h>
2022-07-15 22:27:26 +00:00
#include <Common/EventRateMeter.h>
/// http://en.wikipedia.org/wiki/ANSI_escape_code
#define CLEAR_TO_END_OF_LINE "\033[K"
namespace DB
{
2021-09-17 16:47:54 +00:00
struct ThreadEventData
2021-09-17 15:00:13 +00:00
{
UInt64 time() const noexcept { return user_ms + system_ms; }
2021-09-17 15:00:13 +00:00
UInt64 user_ms = 0;
UInt64 system_ms = 0;
UInt64 memory_usage = 0;
2021-09-17 15:00:13 +00:00
};
2021-09-17 16:47:54 +00:00
using ThreadIdToTimeMap = std::unordered_map<UInt64, ThreadEventData>;
2021-09-17 15:00:13 +00:00
using HostToThreadTimesMap = std::unordered_map<String, ThreadIdToTimeMap>;
class ProgressIndication
{
public:
/// Write progress to stderr.
void writeProgress();
void writeFinalProgress();
/// Clear stderr output.
void clearProgressOutput();
/// Reset progress values.
void resetProgress();
/// Update Progress object. It can be updated from:
/// 1. onProgress in clickhouse-client;
/// 2. ProgressCallback via setProgressCallback methrod in:
/// - context (used in clickhouse-local, can also be added in arbitrary place)
2022-05-20 19:49:31 +00:00
/// - ISource (also in streams)
/// - readBufferFromFileDescriptor (for file processing progress)
bool updateProgress(const Progress & value);
/// 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.
/// `write_progress_on_update` is needed to write progress for loading files data via pipe in non-interactive mode.
void setFileProgressCallback(ContextMutablePtr context, bool write_progress_on_update = false);
/// How much seconds passed since query execution start.
2022-08-08 04:55:41 +00:00
double elapsedSeconds() const { return getElapsedNanoseconds() / 1e9; }
2021-09-15 15:45:43 +00:00
void addThreadIdToList(String const & host, UInt64 thread_id);
2021-09-14 11:06:00 +00:00
2022-07-15 22:27:26 +00:00
void updateThreadEventData(HostToThreadTimesMap & new_thread_data);
2021-09-14 11:06:00 +00:00
private:
2021-09-15 15:45:43 +00:00
size_t getUsedThreadsCount() const;
2022-07-15 22:27:26 +00:00
double getCPUUsage();
struct MemoryUsage
{
UInt64 total = 0;
UInt64 max = 0;
};
MemoryUsage getMemoryUsage() const;
2021-09-17 16:47:54 +00:00
2022-08-08 04:55:41 +00:00
UInt64 getElapsedNanoseconds() const;
/// This flag controls whether to show the progress bar. We start showing it after
/// the query has been executing for 0.5 seconds, and is still less than half complete.
bool show_progress_bar = false;
/// Width of how much has been printed currently into stderr. Used to define size of progress bar and
/// to check whether progress output needs to be cleared.
size_t written_progress_chars = 0;
/// The server periodically sends information about how much data was read since last time.
/// This information is stored here.
Progress progress;
2022-08-08 04:55:41 +00:00
/// Track query execution time on client.
Stopwatch watch;
2021-05-14 08:35:51 +00:00
bool write_progress_on_update = false;
2021-09-14 11:06:00 +00:00
EventRateMeter cpu_usage_meter{static_cast<double>(clock_gettime_ns()), 3'000'000'000 /*ns*/}; // average cpu utilization last 3 second
2021-09-17 16:47:54 +00:00
HostToThreadTimesMap thread_data;
/// In case of all of the above:
/// - clickhouse-local
/// - input_format_parallel_parsing=true
/// - write_progress_on_update=true
///
/// It is possible concurrent access to the following:
/// - writeProgress() (class properties) (guarded with progress_mutex)
2022-07-15 22:27:26 +00:00
/// - thread_data/cpu_usage_meter (guarded with profile_events_mutex)
mutable std::mutex profile_events_mutex;
mutable std::mutex progress_mutex;
};
}