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, utils::Flags<
Flags> flags = {},
65 : Settings(period, kDistributionPercent, flags, span_level) {}
67 constexpr Settings(std::chrono::milliseconds period,
68 std::chrono::milliseconds distribution,
69 utils::Flags<
Flags> flags = {},
72 distribution(distribution),
75 UASSERT(distribution <= period);
78 constexpr Settings(std::chrono::milliseconds period,
79 uint8_t distribution_percent,
80 utils::Flags<
Flags> flags = {},
82 : Settings(period, period * distribution_percent / 100, flags,
84 UASSERT(distribution_percent <= 100);
87 template <
class Rep,
class Period>
88 constexpr Settings(std::chrono::duration<Rep, Period> period)
89 : Settings(period, kDistributionPercent, {},
logging::
Level::kInfo) {}
120 using Callback = std::function<
void()>;
125 PeriodicTask(PeriodicTask&&) =
delete;
126 PeriodicTask(
const PeriodicTask&) =
delete;
133 void Start(std::string name, Settings settings, Callback callback);
192 testsuite::PeriodicTaskControl& periodic_task_control);
198 enum class SuspendState { kRunning, kSuspended };
206 bool StepDebug(
bool preserve_span);
210 std::chrono::milliseconds MutatePeriod(std::chrono::milliseconds period);
212 rcu::Variable<std::string> name_;
215 rcu::Variable<Settings> settings_;
216 engine::SingleConsumerEvent changed_event_;
217 std::atomic<
bool> should_force_step_{
false};
218 std::optional<std::minstd_rand> mutate_period_random_;
221 engine::Mutex step_mutex_;
222 std::atomic<SuspendState> suspend_state_;