11#include <userver/engine/condition_variable.hpp>
12#include <userver/engine/deadline.hpp>
13#include <userver/engine/single_consumer_event.hpp>
14#include <userver/engine/task/task_with_result.hpp>
15#include <userver/rcu/rcu.hpp>
16#include <userver/testsuite/periodic_task_control.hpp>
17#include <userver/tracing/span.hpp>
18#include <userver/utils/assert.hpp>
19#include <userver/utils/flags.hpp>
21USERVER_NAMESPACE_BEGIN
37class PeriodicTask
final {
58 struct Settings
final {
59 static constexpr uint8_t kDistributionPercent = 25;
62 std::chrono::milliseconds period,
utils::Flags<
Flags> flags = {},
64 : Settings(period, kDistributionPercent, flags, span_level) {}
66 constexpr Settings(std::chrono::milliseconds period,
67 std::chrono::milliseconds distribution,
71 distribution(distribution),
74 UASSERT(distribution <= period);
77 constexpr Settings(std::chrono::milliseconds period,
78 uint8_t distribution_percent,
81 : Settings(period, period * distribution_percent / 100, flags,
83 UASSERT(distribution_percent <= 100);
86 template <
class Rep,
class Period>
87 constexpr Settings(std::chrono::duration<Rep, Period> period)
88 : Settings(period, kDistributionPercent, {},
logging::
Level::kInfo) {}
119 using Callback = std::function<
void()>;
124 PeriodicTask(PeriodicTask&&) =
delete;
125 PeriodicTask(
const PeriodicTask&) =
delete;
132 void Start(std::string name, Settings settings, Callback callback);
191 testsuite::PeriodicTaskControl& periodic_task_control);
197 enum class SuspendState { kRunning, kSuspended };
205 bool StepDebug(
bool preserve_span);
209 std::chrono::milliseconds MutatePeriod(std::chrono::milliseconds period);
211 rcu::Variable<std::string> name_;
214 rcu::Variable<Settings> settings_;
215 engine::SingleConsumerEvent changed_event_;
216 std::atomic<
bool> should_force_step_{
false};
219 engine::Mutex step_mutex_;
220 std::atomic<SuspendState> suspend_state_;