1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
6 #include "db/periodic_work_scheduler.h"
8 #include "db/db_impl/db_impl.h"
11 namespace ROCKSDB_NAMESPACE
{
13 PeriodicWorkScheduler::PeriodicWorkScheduler(Env
* env
) : timer_mu_(env
) {
14 timer
= std::unique_ptr
<Timer
>(new Timer(env
));
17 void PeriodicWorkScheduler::Register(DBImpl
* dbi
,
18 unsigned int stats_dump_period_sec
,
19 unsigned int stats_persist_period_sec
) {
20 MutexLock
l(&timer_mu_
);
21 static std::atomic
<uint64_t> initial_delay(0);
23 if (stats_dump_period_sec
> 0) {
24 timer
->Add([dbi
]() { dbi
->DumpStats(); }, GetTaskName(dbi
, "dump_st"),
25 initial_delay
.fetch_add(1) %
26 static_cast<uint64_t>(stats_dump_period_sec
) *
28 static_cast<uint64_t>(stats_dump_period_sec
) * kMicrosInSecond
);
30 if (stats_persist_period_sec
> 0) {
32 [dbi
]() { dbi
->PersistStats(); }, GetTaskName(dbi
, "pst_st"),
33 initial_delay
.fetch_add(1) %
34 static_cast<uint64_t>(stats_persist_period_sec
) * kMicrosInSecond
,
35 static_cast<uint64_t>(stats_persist_period_sec
) * kMicrosInSecond
);
37 timer
->Add([dbi
]() { dbi
->FlushInfoLog(); },
38 GetTaskName(dbi
, "flush_info_log"),
39 initial_delay
.fetch_add(1) % kDefaultFlushInfoLogPeriodSec
*
41 kDefaultFlushInfoLogPeriodSec
* kMicrosInSecond
);
44 void PeriodicWorkScheduler::Unregister(DBImpl
* dbi
) {
45 MutexLock
l(&timer_mu_
);
46 timer
->Cancel(GetTaskName(dbi
, "dump_st"));
47 timer
->Cancel(GetTaskName(dbi
, "pst_st"));
48 timer
->Cancel(GetTaskName(dbi
, "flush_info_log"));
49 if (!timer
->HasPendingTask()) {
54 PeriodicWorkScheduler
* PeriodicWorkScheduler::Default() {
55 // Always use the default Env for the scheduler, as we only use the NowMicros
56 // which is the same for all env.
57 // The Env could only be overridden in test.
58 static PeriodicWorkScheduler
scheduler(Env::Default());
62 std::string
PeriodicWorkScheduler::GetTaskName(DBImpl
* dbi
,
63 const std::string
& func_name
) {
64 std::string db_session_id
;
65 // TODO: Should this error be ignored?
66 dbi
->GetDbSessionId(db_session_id
).PermitUncheckedError();
67 return db_session_id
+ ":" + func_name
;
72 // Get the static scheduler. For a new env, it needs to re-create the internal
73 // timer, so only re-create it when there's no running task. Otherwise, return
74 // the existing scheduler. Which means if the unittest needs to update MockEnv,
75 // Close all db instances and then re-open them.
76 PeriodicWorkTestScheduler
* PeriodicWorkTestScheduler::Default(Env
* env
) {
77 static PeriodicWorkTestScheduler
scheduler(env
);
78 static port::Mutex mutex
;
81 if (scheduler
.timer
.get() != nullptr &&
82 scheduler
.timer
->TEST_GetPendingTaskNum() == 0) {
84 MutexLock
timer_mu_guard(&scheduler
.timer_mu_
);
85 scheduler
.timer
->Shutdown();
87 scheduler
.timer
.reset(new Timer(env
));
93 void PeriodicWorkTestScheduler::TEST_WaitForRun(
94 std::function
<void()> callback
) const {
95 if (timer
!= nullptr) {
96 timer
->TEST_WaitForRun(callback
);
100 size_t PeriodicWorkTestScheduler::TEST_GetValidTaskNum() const {
101 if (timer
!= nullptr) {
102 return timer
->TEST_GetPendingTaskNum();
107 PeriodicWorkTestScheduler::PeriodicWorkTestScheduler(Env
* env
)
108 : PeriodicWorkScheduler(env
) {}
111 } // namespace ROCKSDB_NAMESPACE
113 #endif // ROCKSDB_LITE