12#include <userver/engine/condition_variable.hpp>
13#include <userver/engine/deadline.hpp>
14#include <userver/engine/single_consumer_event.hpp>
15#include <userver/engine/task/task_with_result.hpp>
16#include <userver/rcu/rcu.hpp>
17#include <userver/testsuite/periodic_task_control.hpp>
18#include <userver/tracing/span.hpp>
19#include <userver/utils/assert.hpp>
20#include <userver/utils/flags.hpp>
22USERVER_NAMESPACE_BEGIN
38class PeriodicTask
final {
59 struct Settings
final {
60 static constexpr uint8_t kDistributionPercent = 25;
63 std::chrono::milliseconds period,
67 : Settings(period, kDistributionPercent, flags, span_level) {}
70 std::chrono::milliseconds period,
71 std::chrono::milliseconds distribution,
75 : period(period), distribution(distribution), flags(flags),
span_level(span_level) {
76 UASSERT(distribution <= period);
80 std::chrono::milliseconds period,
81 uint8_t distribution_percent,
85 : Settings(period, period * distribution_percent / 100, flags, span_level) {
86 UASSERT(distribution_percent <= 100);
89 template <
class Rep,
class Period>
90 constexpr Settings(std::chrono::duration<Rep, Period> period)
91 : Settings(period, kDistributionPercent, {},
logging::
Level::kInfo) {}
122 using Callback = std::function<
void()>;
127 PeriodicTask(PeriodicTask&&) =
delete;
128 PeriodicTask(
const PeriodicTask&) =
delete;
135 void Start(std::string name, Settings settings, Callback callback);
199 enum class SuspendState { kRunning, kSuspended };
207 bool StepDebug(
bool preserve_span);
211 std::chrono::milliseconds MutatePeriod(std::chrono::milliseconds period);
213 rcu::Variable<std::string> name_;
216 rcu::Variable<Settings> settings_;
217 engine::SingleConsumerEvent changed_event_;
218 std::atomic<
bool> should_force_step_{
false};
219 std::optional<std::minstd_rand> mutate_period_random_;
222 engine::Mutex step_mutex_;
223 std::atomic<SuspendState> suspend_state_;