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_;