18 #include <condition_variable> 28 using std::chrono::duration_cast;
37 duration_cast<std::chrono::milliseconds>(interval).
count(),
40 for (
int iter = 0; iter < 4; ++iter) {
43 auto const deadline =
now + interval;
44 while (
now < deadline) {
46 std::this_thread::sleep_for(
now - deadline);
50 for (
uint64_t n = 0; n < eventsPerInterval * 2; ++n) {
51 if (n < eventsPerInterval) {
53 <<
"expected check success on loop " << iter <<
" event " << n;
56 <<
"expected check failure on loop " << iter <<
" event " << n;
62 TEST(RateLimiter, interval3per100ms) {
66 TEST(RateLimiter, interval1per100ms) {
70 TEST(RateLimiter, interval15per150ms) {
74 TEST(RateLimiter, concurrentThreads) {
79 std::atomic<uint32_t>
count{0};
81 std::condition_variable cv;
84 auto threadMain = [&]() {
89 std::unique_lock<std::mutex>
lock{m};
90 cv.wait(
lock, [&go] {
return go; });
93 for (
uint64_t iteration = 0; iteration < maxEvents * 2; ++iteration) {
94 if (limiter.check()) {
95 count.fetch_add(1, std::memory_order_relaxed);
101 std::vector<std::thread>
threads;
102 threads.reserve(numThreads);
103 for (
uint64_t n = 0; n < numThreads; ++n) {
104 threads.emplace_back(threadMain);
109 std::lock_guard<std::mutex> lg(m);
115 for (
auto& thread : threads) {
#define EXPECT_EQ(val1, val2)
std::chrono::steady_clock::time_point now()
IntervalRateLimiter::clock irl_clock
#define SCOPED_TRACE(message)
std::vector< std::thread::id > threads
void intervalTest(uint64_t eventsPerInterval, irl_clock::duration interval)
auto lock(SynchronizedLocker...lockersIn) -> std::tuple< typename SynchronizedLocker::LockedPtr... >
static map< string, int > m
#define EXPECT_TRUE(condition)
TEST(RateLimiter, interval3per100ms)
#define EXPECT_FALSE(condition)