File tree Expand file tree Collapse file tree 2 files changed +62
-0
lines changed Expand file tree Collapse file tree 2 files changed +62
-0
lines changed Original file line number Diff line number Diff line change @@ -167,6 +167,37 @@ inline constexpr std::string_view bool_to_alpha(bool b) noexcept
167
167
return b ? " true" : " false" ;
168
168
}
169
169
170
+ // / Throttles the invocation of a callable to not exceed a specified rate.
171
+ // / The rate is controlled by a cooldown interval.
172
+ // /
173
+ // / \tparam ClockT The clock type to use for time points.
174
+ // / \tparam DurationT The duration type for the cooldown interval.
175
+ template <typename ClockT, typename DurationT>
176
+ class ThrottledInvoker {
177
+ using TimePointT = typename ClockT::time_point;
178
+
179
+ public:
180
+ explicit ThrottledInvoker (DurationT cooldown_interval)
181
+ : cooldown_interval_(cooldown_interval) {}
182
+
183
+ template <typename Callable>
184
+ void operator ()(TimePointT now, Callable&& callable)
185
+ {
186
+ if (now < last_time_invoked_) [[unlikely]] {
187
+ return ;
188
+ }
189
+
190
+ if (duration_cast<DurationT>(now - last_time_invoked_) > cooldown_interval_) {
191
+ last_time_invoked_ = now;
192
+ std::forward<Callable>(callable)();
193
+ }
194
+ }
195
+
196
+ private:
197
+ const DurationT cooldown_interval_{};
198
+ TimePointT last_time_invoked_{};
199
+ };
200
+
170
201
} // namespace util
171
202
} // namespace toolbox
172
203
Original file line number Diff line number Diff line change 15
15
// limitations under the License.
16
16
17
17
#include " Utility.hpp"
18
+
19
+ #include < toolbox/sys/Time.hpp>
20
+
18
21
#include < cmath>
19
22
#include < limits>
23
+ #include < thread>
20
24
21
25
#include < boost/test/unit_test.hpp>
22
26
@@ -391,4 +395,31 @@ BOOST_AUTO_TEST_CASE(DecDigitSignedCase)
391
395
BOOST_CHECK_EQUAL (dec_digits (std::int64_t {9223372036854775807 }), 19 );
392
396
}
393
397
398
+ BOOST_AUTO_TEST_CASE (ThrottledInvokerCheck)
399
+ {
400
+ constexpr auto threshold = 1' 000us;
401
+ ThrottledInvoker<MonoClock, Micros> throttler{threshold};
402
+
403
+ std::size_t count = 0 ;
404
+
405
+ auto check_throttling = [&] {
406
+ auto now = MonoClock::now ();
407
+ const auto end = now + threshold;
408
+ while (now < end) {
409
+ throttler (now, [&]() { ++count; });
410
+ now = MonoClock::now ();
411
+ }
412
+ };
413
+
414
+ check_throttling ();
415
+ BOOST_CHECK_EQUAL (count, 1 );
416
+
417
+ // sleep for a bit to pass the cooldown period
418
+ std::this_thread::sleep_for (threshold);
419
+
420
+ // the throttle should invoke again now
421
+ check_throttling ();
422
+ BOOST_CHECK_EQUAL (count, 2 );
423
+ }
424
+
394
425
BOOST_AUTO_TEST_SUITE_END ()
You can’t perform that action at this time.
0 commit comments