Coverage Report

Created: 2026-04-10 07:52

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