Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-73559

Controller freezes due to ratelimiting

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Critical Critical
    • None

      Issue Description

      The GitHub Branch Source Plugin contains ratelimiting strategies to allow requests to GitHub to wait with execution if the ratelimit is (almost) exceeded to prevent them from failing - that is in general a good idea, however it can lead to plenty of Threads being locked at the same time, since Thread.sleep is being used. This then leads to the controller freezing. 

      This happens pretty easily especially with the anonymous rate limit (60 per hour per IP). This is for example used when clicking the "Validate" button in a pipeline configuration to check connectivity.

      Once the ratelimit is now exceeded, you can click that "Validate" button a few times more each processing unit has a Thread waiting for the ratelimit to refresh - Jenkins stops being responsive.

      When using the "Organisations folder" of this plugin, this happens even more likely since organisations make much more anonymous calls.

       

      A real life example: Have an org-scan folder with a few dozen pipelines in it and the credentials expire - now there will be plenty of unauthenticated calls returning 401 - but counting towards the anonymous rate limit. This almost instantly freezes your controller. In our case, not even "sudo reboot" was able to kill the process.

      Not sure, but this downstream locking logic may make this even worse - if one thread waits for this ratelimited-REST call to complete, this call blocks every other thread.

      Sadly it is also not possible to simply ignore this ratelimit. Especially in environments behind a proxy (same outbound IP), this can cause Controllers to freeze pretty easily.

      Reproduction steps

      1) Clone the repository "github-branch-source-plugin"2

      2) Launch a dev instance (mvn hpi:run)

      3) Install the "Monitoring" (Java Melody) plugin, this helps us with debugging this issue.

      4) Create a new multibranch pipeline and select "GitHub" as source type.

      5) Put in any private repository, for example "https://github.com/github/github". Using credentials or not leads to the same result, but with no / invalid credentials, you can reproduce it much faster.

      6) Click on "Validate" a few times until you see that you are being ratelimited in the console, i.e.:

      2024-08-02 12:36:52.280+0000 [id=114]    INFO    o.j.p.g.ApiRateLimitChecker$RateLimitCheckerAdapter#checkRateLimit: Jenkins-Imposed API Limiter: Current quota for Github API usage has 12 remaining (3 over budget). Next quota of 60 in 15 min. Sleeping until reset.

      7) Open the Monitor at http://localhost:8080/jenkins/monitoring?.

      Already now you will see that there is a sleeping Thread. There should be "1 current request"

      Now, click the button a few more times until your CPU is completely occupied with sleeping threads.

      Killing these threads via Java Melody will not help (if you even get through to that)

      Possible solutions

      I am really no expert with multithreading in Java, but this is what I thought of.

      1) Use ScheduledExecutorService instead of Thread.sleep, however I do not have any experience with this so I would need a secondary opinion.

      2) Allow to define a timeout for waiting for free rate limits

      3) Allow the "Ignore Ratelimit" strategy for GitHub.com as well

            Unassigned Unassigned
            meiswjn Jan
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: