Line data Source code
1 : #include "source/common/config/ttl.h" 2 : 3 : namespace Envoy { 4 : namespace Config { 5 : 6 : TtlManager::TtlManager(std::function<void(const std::vector<std::string>&)> callback, 7 : Event::Dispatcher& dispatcher, TimeSource& time_source) 8 139 : : callback_(callback), dispatcher_(dispatcher), time_source_(time_source) { 9 139 : timer_ = dispatcher_.createTimer([this]() { 10 0 : ScopedTtlUpdate scoped_update(*this); 11 : 12 0 : std::vector<std::string> expired; 13 0 : last_scheduled_time_ = absl::nullopt; 14 : 15 0 : const auto now = time_source_.monotonicTime(); 16 0 : auto itr = ttls_.begin(); 17 0 : while (itr != ttls_.end() && itr->first <= now) { 18 0 : expired.push_back(itr->second); 19 0 : ttl_lookup_.erase(itr->second); 20 0 : itr++; 21 0 : } 22 : 23 0 : if (itr != ttls_.begin()) { 24 0 : ttls_.erase(ttls_.begin(), itr); 25 0 : } 26 : 27 0 : if (!expired.empty()) { 28 0 : callback_(expired); 29 0 : } 30 0 : }); 31 139 : } 32 0 : void TtlManager::add(std::chrono::milliseconds ttl, const std::string& name) { 33 0 : ScopedTtlUpdate scoped_update(*this); 34 : 35 0 : clear(name); 36 : 37 0 : auto itr_and_inserted = ttls_.insert({time_source_.monotonicTime() + ttl, name}); 38 0 : ttl_lookup_[name] = itr_and_inserted.first; 39 0 : } 40 : 41 328 : void TtlManager::clear(const std::string& name) { 42 328 : ScopedTtlUpdate scoped_update(*this); 43 : 44 328 : auto lookup_itr = ttl_lookup_.find(name); 45 328 : if (lookup_itr != ttl_lookup_.end()) { 46 0 : ttls_.erase(lookup_itr->second); 47 0 : ttl_lookup_.erase(lookup_itr); 48 0 : } 49 328 : } 50 : 51 222 : void TtlManager::refreshTimer() { 52 : // No TTLs, so just disable the timer. 53 222 : if (ttls_.empty()) { 54 222 : timer_->disableTimer(); 55 222 : return; 56 222 : } 57 : 58 0 : auto next_ttl_expiry = ttls_.begin()->first; 59 : 60 : // The currently scheduled timer execution matches the next TTL expiry, so do nothing. 61 0 : if (timer_->enabled() && last_scheduled_time_ == next_ttl_expiry) { 62 0 : return; 63 0 : } 64 : 65 0 : auto timer_duration = std::chrono::duration_cast<std::chrono::milliseconds>( 66 0 : next_ttl_expiry - time_source_.monotonicTime()); 67 : 68 : // The time until the next TTL changed, so reset the timer to match the new value. 69 0 : last_scheduled_time_ = next_ttl_expiry; 70 0 : timer_->enableTimer(timer_duration, nullptr); 71 0 : } 72 : } // namespace Config 73 : } // namespace Envoy