'How to shortly delay a http request until a resource is free
I have a small spring-boot application, let's say it is called "ABC" which has to get a part of information from an external web-service, let's call it "ext resource". The problem is that the policy of that external service doesn't allow more than 60 requests per minute. Otherwise I would get a warning from them. I searched the web, but couldn't find any solution for this. I was thinking to limit requests to 1 request per second (which then comes to 60 requests per minute).
When clients (browser) send requests to my "ABC" server, how can I distribute them into 1 second raster? Asked another way, if necessary, how can I delay http requests, until "ext resource" is free again? In the period of 1 sec. only one client's request may use "ext resource". First thought I had was to do Thread.sleep(1000) and then re-check if "the resource" is free, but I'm not sure if I should use Thread.sleep inside a web-app running on Apache Tomcat. I guess I cannot use any ansynchronous methods, because clients must wait for some results, so the whole request must be synchronous. I "just" need to delay client's request for a while until my server-side application "ABC" is allowed to contact "ext resourse" again. How can I do this and which technique would you recommend for this kind of "synchronization"?
I'm kind of old-school Java Developer and still not into this newer stuff like Futures/Promises. I took a look at them, but from what I saw that's all asynchronous stuff (I searched in Internet for some hours now).
Thank you very much for any help!
Solution 1:[1]
You could do something like this:
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.atomic.AtomicInteger;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class RequestThrottlerService {
AtomicInteger requestCount = new AtomicInteger(1);
/** Every minute **/
@Scheduled(cron = "0 * * * * *")
synchronized public void resetRequests() {
log.info("Reset the request count.");
requestCount.set(1);
notifyAll();
}
public void makeThrottledRequest() throws InterruptedException {
int count = requestCount.getAndIncrement();
while (count > 60) {
synchronized(this) {
log.info("Request " + requestCount.get() + " for this minute is waiting!");
wait();
}
count = requestCount.getAndIncrement();
}
log.info("Request " + requestCount.get() + " for this minute is running");
/* ##### execute your synchronous request here ##### */
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Hopey One |
