userver: userver/utils/trx_tracker.hpp Source File
Loading...
Searching...
No Matches
trx_tracker.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/utils/trx_tracker.hpp
4/// @brief Tracking for heavy operations while having active transactions.
5
6#include <optional>
7#include <thread>
8
9#include <userver/utils/impl/source_location.hpp>
10#include <userver/utils/statistics/rate.hpp>
11
12USERVER_NAMESPACE_BEGIN
13
14/// @brief Tracking for heavy operations while having active transactions.
15///
16/// Some operations, like HTTP requests, are heavy and can take too long during an incident. If they are called during
17/// an active database transaction, connection will be held for longer and connection pool will be exhausted.
18/// Transaction tracker prevents this by holding counter of active transactions in TaskLocalVariable
19/// and checking for active transactions in heavy operations.
20///
21/// ## Example usage:
22///
23/// @snippet utils/trx_tracker_test.cpp Sample TransactionTracker usage
24///
25/// @see @ref scripts/docs/en/userver/long_transactions.md
26namespace utils::trx_tracker {
27
28namespace impl {
29
30/// @brief Global enabler for transaction tracker.
31class GlobalEnabler final {
32public:
33 explicit GlobalEnabler(bool enable = true);
34 ~GlobalEnabler();
35
36 GlobalEnabler(const GlobalEnabler&) = delete;
37 GlobalEnabler& operator=(const GlobalEnabler&) = delete;
38};
39
40/// @brief Check if transaction tracker is enabled.
41bool IsEnabled() noexcept;
42
43/// @brief Unique ID for every task.
44///
45/// Sometimes transactions start and end in different coroutines. To prevent transaction from incrementing and
46/// decrementing different transaction counters, TransactionLock stores TaskId on Lock and
47/// checks that stored TaskId is the same as current TaskId in Unlock.
48class TaskId final {
49public:
50 TaskId();
51
52 bool operator==(const TaskId& other) const;
53
54private:
55 std::thread::id created_thread_id_;
56 std::uint64_t thread_local_counter_;
57};
58
59} // namespace impl
60
61/// @brief Class for incrementing and decrementing transaction counter.
62class TransactionLock final {
63public:
64 TransactionLock() = default;
65 TransactionLock(const TransactionLock&) = delete;
66 TransactionLock(TransactionLock&&) noexcept;
67 TransactionLock operator=(const TransactionLock&) = delete;
68 TransactionLock& operator=(TransactionLock&&) noexcept;
69
70 /// @brief Decrement transaction counter on destruction.
72
73 /// @brief Manually increment transaction counter.
74 void Lock() noexcept;
75
76 /// @brief Manually decrement transaction counter.
77 void Unlock() noexcept;
78
79private:
80 std::optional<impl::TaskId> task_id_;
81};
82
83/// @brief Check for active transactions.
84void CheckNoTransactions(utils::impl::SourceLocation location = utils::impl::SourceLocation::Current());
85
86/// @overload
87void CheckNoTransactions(std::string_view location);
88
89/// @brief Disable check for active transactions.
90///
91/// To consciously call a heavy operation in active transaction, check can be disabled by creating an instance of this
92/// class. Checks will be disabled until every instance either has Reenable() method called or is destroyed.
93///
94/// @snippet utils/trx_tracker_test.cpp Sample CheckDisabler usage
95class CheckDisabler final {
96public:
97 /// @brief Disable check for active transactions.
98 explicit CheckDisabler();
99
100 /// @brief Reenable check for active transactions on destruction.
102
103 CheckDisabler(const CheckDisabler&) = delete;
104 CheckDisabler(CheckDisabler&&) = delete;
105 CheckDisabler operator=(const CheckDisabler&) = delete;
106 CheckDisabler operator=(CheckDisabler&&) = delete;
107
108 /// @brief Manually reenable check for active transactions.
109 void Reenable() noexcept;
110
111private:
112 bool reenabled_ = false;
113};
114
115/// @brief Statistics for transaction tracker.
116struct TransactionTrackerStatistics final {
117 /// @brief How many times check for active transactions was triggered.
119};
120
121/// @brief Get statistics for transaction tracker.
122TransactionTrackerStatistics GetStatistics() noexcept;
123
124/// @brief Reset statistics for transaction tracker.
126
127} // namespace utils::trx_tracker
128
129USERVER_NAMESPACE_END