Line data Source code
1 : #pragma once 2 : 3 : #include <chrono> 4 : 5 : #include "envoy/event/dispatcher.h" 6 : #include "envoy/event/timer.h" 7 : 8 : namespace Envoy { 9 : namespace Config { 10 : 11 : /** 12 : * Class for managing TTL expiration of xDS resources. TTLs are managed with a single timer that 13 : * will always be set to the time until the next TTL, ensuring that we have a constant amount of 14 : * timers per xDS resource type. 15 : * 16 : * We use a combination of two data structures here: a std::set that ensures that we can iterate 17 : * over the pending TTLs in sorted over, and a map from resource name to the set iterator which 18 : * allows us to efficiently clear or update TTLs. As iterator stability is required to track the 19 : * iterators, we use std::set over something like ``absl::btree_set``. 20 : * 21 : * As a result of these two data structures, all lookups and modifications can be performed in 22 : * O(log (number of TTL entries)). This comes at the cost of a higher memory overhead versus just 23 : * using a single data structure. 24 : */ 25 : class TtlManager { 26 : public: 27 : TtlManager(std::function<void(const std::vector<std::string>&)> callback, 28 : Event::Dispatcher& dispatcher, TimeSource& time_source); 29 : 30 : // RAII tracker to simplify managing when we should be running the update callbacks. 31 : class ScopedTtlUpdate { 32 : public: 33 550 : ~ScopedTtlUpdate() { 34 550 : if (--parent_.scoped_update_counter_ == 0) { 35 222 : parent_.refreshTimer(); 36 222 : } 37 550 : } 38 : 39 : private: 40 550 : ScopedTtlUpdate(TtlManager& parent) : parent_(parent) { parent_.scoped_update_counter_++; } 41 : 42 : friend TtlManager; 43 : 44 : TtlManager& parent_; 45 : }; 46 : 47 222 : ScopedTtlUpdate scopedTtlUpdate() { return {*this}; } 48 : 49 : void add(std::chrono::milliseconds ttl, const std::string& name); 50 : 51 : void clear(const std::string& name); 52 : 53 : private: 54 : void refreshTimer(); 55 : 56 : using TtlSet = std::set<std::pair<MonotonicTime, std::string>>; 57 : TtlSet ttls_; 58 : absl::flat_hash_map<std::string, TtlSet::iterator> ttl_lookup_; 59 : 60 : Event::TimerPtr timer_; 61 : absl::optional<MonotonicTime> last_scheduled_time_; 62 : uint8_t scoped_update_counter_{}; 63 : 64 : std::function<void(const std::vector<std::string>&)> callback_; 65 : Event::Dispatcher& dispatcher_; 66 : TimeSource& time_source_; 67 : }; 68 : } // namespace Config 69 : } // namespace Envoy