]>
Commit | Line | Data |
---|---|---|
1e59de90 TL |
1 | // Copyright (c) Meta Platforms, Inc. and affiliates. |
2 | // | |
3 | // This source code is licensed under both the GPLv2 (found in the | |
4 | // COPYING file in the root directory) and Apache 2.0 License | |
5 | // (found in the LICENSE.Apache file in the root directory). | |
6 | ||
7 | #pragma once | |
8 | ||
9 | #ifndef ROCKSDB_LITE | |
10 | ||
11 | #include "util/timer.h" | |
12 | ||
13 | namespace ROCKSDB_NAMESPACE { | |
14 | class SystemClock; | |
15 | ||
16 | using PeriodicTaskFunc = std::function<void()>; | |
17 | ||
18 | constexpr uint64_t kInvalidPeriodSec = 0; | |
19 | ||
20 | // List of task types | |
21 | enum class PeriodicTaskType : uint8_t { | |
22 | kDumpStats = 0, | |
23 | kPersistStats, | |
24 | kFlushInfoLog, | |
25 | kRecordSeqnoTime, | |
26 | kMax, | |
27 | }; | |
28 | ||
29 | // PeriodicTaskScheduler contains the periodic task scheduled from the DB | |
30 | // instance. It's used to schedule/unschedule DumpStats(), PersistStats(), | |
31 | // FlushInfoLog(), etc. Each type of the task can only have one instance, | |
32 | // re-register the same task type would only update the repeat period. | |
33 | // | |
34 | // Internally, it uses a global single threaded timer object to run the periodic | |
35 | // task functions. Timer thread will always be started since the info log | |
36 | // flushing cannot be disabled. | |
37 | class PeriodicTaskScheduler { | |
38 | public: | |
39 | explicit PeriodicTaskScheduler() = default; | |
40 | ||
41 | PeriodicTaskScheduler(const PeriodicTaskScheduler&) = delete; | |
42 | PeriodicTaskScheduler(PeriodicTaskScheduler&&) = delete; | |
43 | PeriodicTaskScheduler& operator=(const PeriodicTaskScheduler&) = delete; | |
44 | PeriodicTaskScheduler& operator=(PeriodicTaskScheduler&&) = delete; | |
45 | ||
46 | // Register a task with its default repeat period | |
47 | Status Register(PeriodicTaskType task_type, const PeriodicTaskFunc& fn); | |
48 | ||
49 | // Register a task with specified repeat period. 0 is an invalid argument | |
50 | // (kInvalidPeriodSec). To stop the task, please use Unregister() specifically | |
51 | Status Register(PeriodicTaskType task_type, const PeriodicTaskFunc& fn, | |
52 | uint64_t repeat_period_seconds); | |
53 | ||
54 | // Unregister the task | |
55 | Status Unregister(PeriodicTaskType task_type); | |
56 | ||
57 | #ifndef NDEBUG | |
58 | // Override the timer for the unittest | |
59 | void TEST_OverrideTimer(SystemClock* clock); | |
60 | ||
61 | // Call Timer TEST_WaitForRun() which wait until Timer starting waiting. | |
62 | void TEST_WaitForRun(const std::function<void()>& callback) const { | |
63 | if (timer_ != nullptr) { | |
64 | timer_->TEST_WaitForRun(callback); | |
65 | } | |
66 | } | |
67 | ||
68 | // Get global valid task number in the Timer | |
69 | size_t TEST_GetValidTaskNum() const { | |
70 | if (timer_ != nullptr) { | |
71 | return timer_->TEST_GetPendingTaskNum(); | |
72 | } | |
73 | return 0; | |
74 | } | |
75 | ||
76 | // If it has the specified task type registered | |
77 | bool TEST_HasTask(PeriodicTaskType task_type) const { | |
78 | auto it = tasks_map_.find(task_type); | |
79 | return it != tasks_map_.end(); | |
80 | } | |
81 | #endif // NDEBUG | |
82 | ||
83 | private: | |
84 | // default global Timer instance | |
85 | static Timer* Default(); | |
86 | ||
87 | // Internal structure to store task information | |
88 | struct TaskInfo { | |
89 | TaskInfo(std::string _name, uint64_t _repeat_every_sec) | |
90 | : name(std::move(_name)), repeat_every_sec(_repeat_every_sec) {} | |
91 | std::string name; | |
92 | uint64_t repeat_every_sec; | |
93 | }; | |
94 | ||
95 | // Internal tasks map | |
96 | std::map<PeriodicTaskType, TaskInfo> tasks_map_; | |
97 | ||
98 | // Global timer pointer, which doesn't support synchronous add/cancel tasks | |
99 | // so having a global `timer_mutex` for add/cancel task. | |
100 | Timer* timer_ = Default(); | |
101 | ||
102 | // Global task id, protected by the global `timer_mutex` | |
103 | inline static uint64_t id_; | |
104 | ||
105 | static constexpr uint64_t kMicrosInSecond = 1000U * 1000U; | |
106 | }; | |
107 | ||
108 | } // namespace ROCKSDB_NAMESPACE | |
109 | ||
110 | #endif // ROCKSDB_LITE |