1#pragma once
2
3#include <memory>
4#include <string>
5
6#include <common/likely.h>
7#include <common/StringRef.h>
8#include <Common/ThreadStatus.h>
9
10
11namespace ProfileEvents
12{
13class Counters;
14}
15
16class MemoryTracker;
17
18
19namespace DB
20{
21
22class Context;
23class QueryStatus;
24struct Progress;
25class InternalTextLogsQueue;
26
27
28/** Collection of static methods to work with thread-local objects.
29 * Allows to attach and detach query/process (thread group) to a thread
30 * (to calculate query-related metrics and to allow to obtain query-related data from a thread).
31 * Thread will propagate it's metrics to attached query.
32 */
33class CurrentThread
34{
35public:
36 /// Return true in case of successful initializaiton
37 static bool isInitialized();
38
39 /// Handler to current thread
40 static ThreadStatus & get();
41
42 /// Group to which belongs current thread
43 static ThreadGroupStatusPtr getGroup();
44
45 /// A logs queue used by TCPHandler to pass logs to a client
46 static void attachInternalTextLogsQueue(const std::shared_ptr<InternalTextLogsQueue> & logs_queue,
47 LogsLevel client_logs_level);
48 static std::shared_ptr<InternalTextLogsQueue> getInternalTextLogsQueue();
49
50 /// Makes system calls to update ProfileEvents that contain info from rusage and taskstats
51 static void updatePerformanceCounters();
52
53 static ProfileEvents::Counters & getProfileEvents();
54 static MemoryTracker * getMemoryTracker();
55
56 static inline Int64 & getUntrackedMemory()
57 {
58 /// It assumes that (current_thread != nullptr) is already checked with getMemoryTracker()
59 return current_thread->untracked_memory;
60 }
61
62 /// Update read and write rows (bytes) statistics (used in system.query_thread_log)
63 static void updateProgressIn(const Progress & value);
64 static void updateProgressOut(const Progress & value);
65
66 /// Query management:
67
68 /// Call from master thread as soon as possible (e.g. when thread accepted connection)
69 static void initializeQuery();
70
71 /// Sets query_context for current thread group
72 static void attachQueryContext(Context & query_context);
73
74 /// You must call one of these methods when create a query child thread:
75 /// Add current thread to a group associated with the thread group
76 static void attachTo(const ThreadGroupStatusPtr & thread_group);
77 /// Is useful for a ThreadPool tasks
78 static void attachToIfDetached(const ThreadGroupStatusPtr & thread_group);
79
80 /// Update ProfileEvents and dumps info to system.query_thread_log
81 static void finalizePerformanceCounters();
82
83 /// Returns a non-empty string if the thread is attached to a query
84 static StringRef getQueryId()
85 {
86 if (unlikely(!current_thread))
87 return {};
88 return current_thread->getQueryId();
89 }
90
91 /// Non-master threads call this method in destructor automatically
92 static void detachQuery();
93 static void detachQueryIfNotDetached();
94
95 /// Initializes query with current thread as master thread in constructor, and detaches it in destructor
96 struct QueryScope
97 {
98 explicit QueryScope(Context & query_context);
99 ~QueryScope();
100
101 void logPeakMemoryUsage();
102 bool log_peak_memory_usage_in_destructor = true;
103 };
104
105private:
106 static void defaultThreadDeleter();
107};
108
109}
110
111