question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Need help understanding why rate limiter doesn't behave like I think it should?

See original GitHub issue

Hi,

I’m using resilience4j and the rate-limiting module together with Spring project reactor. The code I have looks essentially like this:

public class App {


    private final WebClient webClient;
    private final InMemoryRateLimiterRegistry rateLimiterRegistry;

    public App(int port, int rps) {
        webClient = WebClient.builder()
                .baseUrl("http://localhost:" + port)
                .build();

        rateLimiterRegistry = new InMemoryRateLimiterRegistry(RateLimiterConfig.ofDefaults());
        rateLimiterRegistry.rateLimiter("test", RateLimiterConfig.custom()
                .limitRefreshPeriod(Duration.ofSeconds(1))
                .limitForPeriod(rps)
                .timeoutDuration(Duration.ofHours(1))
                .build());
    }

    public Mono<String> makeRequest() {
        RateLimiter rateLimiter = rateLimiterRegistry.rateLimiter("test");
        Mono<String> result = webClient.post()
                .uri("/testing")
                .accept(ALL)
                .contentType(TEXT_PLAIN)
                .syncBody("hello world")
                .retrieve().bodyToMono(String.class);

        return result.transform(RateLimiterOperator.of(rateLimiter));
    }
}

I’ve tried creating a test case in which I’d like to verify that the rate limiter actually limits the requests per second to 10. The test case looks like this:

public class AppTest {

    @Rule
    public WireMockRule wireMockRule = new WireMockRule();

    @Test
    public void whyDoesntThisWorkQuestionMarkQuestionMark() {
        // Given
        int numberOfRequests = 30;
        int rps = 10;
        App app = new App(wireMockRule.port(), rps);

        wireMockRule.addStubMapping(stubFor(post(urlPathEqualTo("/testing"))
                .willReturn(aResponse().withStatus(200).withBody("hello hello!"))));

        // When
        ParallelFlux<String> flux = Flux.range(0, numberOfRequests)
                .parallel()
                .runOn(Schedulers.parallel())
                .flatMap(___ -> app.makeRequest());

        long startTime = new Date().getTime();
        StepVerifier.create(flux).expectNextCount(numberOfRequests).verifyComplete();
        long endTime = new Date().getTime();

        assertThat(endTime - startTime)
                .describedAs("I don't understand why this is not taking longer than this")
                .isGreaterThanOrEqualTo((numberOfRequests / rps) * 1000);
    }
}

But this fails with:

whyDoesntThisWorkQuestionMarkQuestionMark(se.haleby.AppTest)  Time elapsed: 2.376 sec  <<< FAILURE!
java.lang.AssertionError: [I don't understand why this is not taking longer than this] 
Expecting:
 <1466L>
to be greater than or equal to:
 <3000L> 
        at se.haleby.AppTest.whyDoesntThisWorkQuestionMarkQuestionMark(AppTest.java:43)

I don’t really understand why the test is only taking roughly 1,5 seconds instead of the expected 3 seconds (since I’m making 30 requests with an RPS of 10 requests per second). I’m probably missing something quite essential here and I’m ready to be schooled 😃.

My code can be found here: https://github.com/johanhaleby/resilience4j-ratelimiter-question

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:24 (22 by maintainers)

github_iconTop GitHub Comments

3reactions
johanhalebycommented, May 21, 2019

@RobWin Oh, that probably explains it. I think I get it now and it makes sense. Thanks a lot for taking the time to explain this, really appreciated. And thanks for all the work on resilience4j.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Rate-limiting strategies and techniques - Google Cloud
Introduction. This document explains why rate limiting is used, describes strategies and techniques for rate limiting, and explains where ...
Read more >
Rate Limiting: What It Is & Why It Matters | Traefik Labs
Rate limiting your network traffic is critical to ensuring your infrastructure remains resilient and secure. Read our 101 article to learn more.
Read more >
Rate Limiting and Velocity Checking - Coding Horror
Rate limiting isn't always a precise science. But it's necessary, even with the false positives -- consider how dangerous a login entry with...
Read more >
What is rate limiting? | Rate limiting and bots - Cloudflare
Typically, rate limiting is based on tracking the IP addresses that requests are coming from, and tracking how much time elapses between each...
Read more >
How to Design a Scalable Rate Limiting Algorithm with Kong API
Without rate limiting, each user may make a request as often as they like, leading to “spikes” of requests that starve other consumers....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found