From ac22b59a40cd7607ab19ff334a7f524f6f943667 Mon Sep 17 00:00:00 2001 From: Michael Carlberg Date: Tue, 21 Jun 2016 04:16:55 +0200 Subject: [PATCH] feat: EventThrottler --- include/services/event_throttler.hpp | 31 +++++++++++++++++++++ src/CMakeLists.txt | 1 + src/services/event_throttler.cpp | 40 ++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 include/services/event_throttler.hpp create mode 100644 src/services/event_throttler.cpp diff --git a/include/services/event_throttler.hpp b/include/services/event_throttler.hpp new file mode 100644 index 00000000..cd3c0040 --- /dev/null +++ b/include/services/event_throttler.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +#include +#include + +namespace event_throttler +{ + typedef std::chrono::duration timewindow_t; + typedef std::chrono::high_resolution_clock timepoint_clock_t; + typedef event_throttler::timepoint_clock_t::time_point timepoint_t; + typedef std::deque queue_t; + typedef std::size_t limit_t; +} + +class EventThrottler +{ + event_throttler::queue_t event_queue; + event_throttler::limit_t passthrough_limit; + event_throttler::timewindow_t timewindow; + + protected: + void expire(); + + public: + explicit EventThrottler(int limit, event_throttler::timewindow_t timewindow) + : passthrough_limit(limit), timewindow(timewindow) {} + + bool passthrough(); +}; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9967d678..1d223aab 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -43,6 +43,7 @@ set(SOURCE_FILES "src/modules/text.cpp" "src/services/builder.cpp" "src/services/command.cpp" + "src/services/event_throttler.cpp" "src/services/inotify.cpp" "src/services/logger.cpp" # "src/services/store.cpp" diff --git a/src/services/event_throttler.cpp b/src/services/event_throttler.cpp new file mode 100644 index 00000000..688aa8fd --- /dev/null +++ b/src/services/event_throttler.cpp @@ -0,0 +1,40 @@ +#include + +#include "services/event_throttler.hpp" +#include "services/logger.hpp" + +using namespace event_throttler; + +bool EventThrottler::passthrough() +{ + // Remove expired frames from the queue + this->expire(); + + // Place the new frame in the bottom of the deck + this->event_queue.emplace_back(timepoint_clock_t::now()); + + // Check if the limit has been reached + if (this->event_queue.size() >= this->passthrough_limit) { + // std::this_thread::sleep_for(this->timewindow * this->event_queue.size()); + std::this_thread::sleep_for(this->timewindow); + + if (this->event_queue.size() - 1 >= this->passthrough_limit) { + log_trace("Event passthrough throttled"); + return false; + } + } + + return true; +} + +void EventThrottler::expire() +{ + auto now = timepoint_clock_t::now(); + + while (this->event_queue.size() > 0) { + if ((now - this->event_queue.front()) < this->timewindow) + break; + + this->event_queue.pop_front(); + } +}