Line data Source code
1 : #include "source/extensions/tracers/datadog/event_scheduler.h" 2 : 3 : #include <memory> 4 : #include <utility> 5 : 6 : #include "source/common/common/assert.h" 7 : 8 : #include "datadog/json.hpp" 9 : 10 : namespace Envoy { 11 : namespace Extensions { 12 : namespace Tracers { 13 : namespace Datadog { 14 : 15 0 : EventScheduler::EventScheduler(Event::Dispatcher& dispatcher) : dispatcher_(dispatcher) {} 16 : 17 : EventScheduler::Cancel 18 : EventScheduler::schedule_recurring_event(std::chrono::steady_clock::duration interval, 19 0 : std::function<void()> callback) { 20 0 : auto self = std::make_shared<Event::Timer*>(); 21 : // Yes, a shared pointer to a pointer. 22 : // 23 : // Both the timer callback (argument to `createTimer`, below) and the returned 24 : // cancellation function need a handle to the `Event::Timer`. The timer 25 : // callback needs it so that it can reschedule the next round when the timer 26 : // fires (that's how this is a _recurring_ event). The cancellation function 27 : // needs it so that it can call `disableTimer` and remove the timer from 28 : // `timers_`. 29 : // 30 : // Since we don't have a handle to the `Event::Timer` until `createTimer` 31 : // returns, we need a "box" out of which the timer callback can extract the 32 : // created timer. We then put the `Event::Timer*` in the "box" after 33 : // `createTimer` returns the timer. `self` is the "box." 34 : // 35 : // The cancellation function returned by this function refers to the 36 : // `Event::Timer` via a raw pointer (as does the timer callback, indirectly). 37 : // The actual lifetime of the pointed-to `Event::Timer` is determined by its 38 : // presence in `timers_`. The `Event::TimerPtr` returned by `createTimer` is 39 : // moved into `timers_`. 40 : 41 0 : Event::TimerPtr timer = dispatcher_.createTimer([self, interval, callback = std::move(callback)] { 42 0 : (**self).enableTimer(std::chrono::duration_cast<std::chrono::milliseconds>(interval)); 43 0 : callback(); 44 0 : }); 45 : 46 0 : Event::Timer* timer_raw = timer.get(); 47 0 : *self = timer_raw; 48 : 49 0 : timers_.insert(std::move(timer)); 50 : 51 0 : timer_raw->enableTimer(std::chrono::duration_cast<std::chrono::milliseconds>(interval)); 52 : 53 0 : return [this, timer = timer_raw]() mutable { 54 0 : if (!timer) { 55 0 : return; // idempotent 56 0 : } 57 : 58 0 : timer->disableTimer(); 59 0 : auto found = timers_.find(timer); 60 0 : RELEASE_ASSERT(found != timers_.end(), 61 0 : "timer not found in registry of timers in Datadog::EventScheduler"); 62 0 : timers_.erase(found); 63 0 : timer = nullptr; 64 0 : }; 65 0 : } 66 : 67 0 : nlohmann::json EventScheduler::config_json() const { 68 0 : return nlohmann::json::object({ 69 0 : {"type", "Envoy::Extensions::Tracers::Datadog::EventScheduler"}, 70 0 : }); 71 0 : } 72 : 73 : } // namespace Datadog 74 : } // namespace Tracers 75 : } // namespace Extensions 76 : } // namespace Envoy