| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- // Copyright (c) Meta Platforms, Inc. and affiliates.
- //
- // This source code is licensed under both the GPLv2 (found in the
- // COPYING file in the root directory) and Apache 2.0 License
- // (found in the LICENSE.Apache file in the root directory).
- #pragma once
- #include "util/timer.h"
- namespace ROCKSDB_NAMESPACE {
- class SystemClock;
- using PeriodicTaskFunc = std::function<void()>;
- constexpr uint64_t kInvalidPeriodSec = 0;
- // List of task types
- enum class PeriodicTaskType : uint8_t {
- kDumpStats = 0,
- kPersistStats,
- kFlushInfoLog,
- kRecordSeqnoTime,
- kTriggerCompaction,
- kMax,
- };
- // PeriodicTaskScheduler contains the periodic task scheduled from the DB
- // instance. It's used to schedule/unschedule DumpStats(), PersistStats(),
- // FlushInfoLog(), etc. Each type of the task can only have one instance,
- // re-register the same task type would only update the repeat period.
- //
- // Internally, it uses a global single threaded timer object to run the periodic
- // task functions. Timer thread will always be started since the info log
- // flushing cannot be disabled.
- class PeriodicTaskScheduler {
- public:
- explicit PeriodicTaskScheduler() = default;
- PeriodicTaskScheduler(const PeriodicTaskScheduler&) = delete;
- PeriodicTaskScheduler(PeriodicTaskScheduler&&) = delete;
- PeriodicTaskScheduler& operator=(const PeriodicTaskScheduler&) = delete;
- PeriodicTaskScheduler& operator=(PeriodicTaskScheduler&&) = delete;
- // Register a task with its default repeat period. Thread safe call.
- // @param run_immediately If true, the task will run soon after it's
- // scheduled, instead of waiting for the repeat period.
- Status Register(PeriodicTaskType task_type, const PeriodicTaskFunc& fn,
- bool run_immediately);
- // Register a task with specified repeat period. 0 is an invalid argument
- // (kInvalidPeriodSec). To stop the task, please use Unregister().
- // Thread safe call.
- Status Register(PeriodicTaskType task_type, const PeriodicTaskFunc& fn,
- uint64_t repeat_period_seconds, bool run_immediately);
- // Unregister the task. Thread safe call.
- Status Unregister(PeriodicTaskType task_type);
- #ifndef NDEBUG
- // Override the timer for the unittest
- void TEST_OverrideTimer(SystemClock* clock);
- // Call Timer TEST_WaitForRun() which wait until Timer starting waiting.
- void TEST_WaitForRun(const std::function<void()>& callback) const {
- if (timer_ != nullptr) {
- timer_->TEST_WaitForRun(callback);
- }
- }
- // Get global valid task number in the Timer
- size_t TEST_GetValidTaskNum() const {
- if (timer_ != nullptr) {
- return timer_->TEST_GetPendingTaskNum();
- }
- return 0;
- }
- // If it has the specified task type registered
- bool TEST_HasTask(PeriodicTaskType task_type) const {
- auto it = tasks_map_.find(task_type);
- return it != tasks_map_.end();
- }
- #endif // NDEBUG
- private:
- // default global Timer instance
- static Timer* Default();
- // Internal structure to store task information
- struct TaskInfo {
- TaskInfo(std::string _name, uint64_t _repeat_every_sec)
- : name(std::move(_name)), repeat_every_sec(_repeat_every_sec) {}
- std::string name;
- uint64_t repeat_every_sec;
- };
- // Internal tasks map
- std::map<PeriodicTaskType, TaskInfo> tasks_map_;
- // Global timer pointer, which doesn't support synchronous add/cancel tasks
- // so having a global `timer_mutex` for add/cancel task.
- Timer* timer_ = Default();
- // Global task id, protected by the global `timer_mutex`
- inline static uint64_t id_;
- static constexpr uint64_t kMicrosInSecond = 1000U * 1000U;
- };
- } // namespace ROCKSDB_NAMESPACE
|