Scenario
Since the third-party API has a rate limit, I need to send requests one by one, with a delay between each call.
So I create a simple solution to do it!
Solution
// ApiService import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.util.Map; @Slf4j @Service public class ApiService { public void executeApi(BlockingQueueService.Request request) throws InterruptedException { // log.info("[jobId-{}] API_SERVICE > START", request.getId()); Thread.sleep(request.getRunTime()); // log.info("[jobId-{}] API_SERVICE > STOP", request.getId()); } }
// BlockingQueueService import lombok.Data; import lombok.ToString; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.concurrent.*; @Slf4j @Service public class BlockingQueueService { @Autowired private ApiService apiService; private final int POOL_SIZE = 1; private final BlockingQueue<Request> queue = new LinkedBlockingQueue<>(); private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(POOL_SIZE); public BlockingQueueService() { log.info("INIT BLOCKING QUEUE SERVICE"); for (int i = 0; i < POOL_SIZE; i++) { int workerId = i + 1; executor.scheduleAtFixedRate(() -> processQueue(workerId), 0, 2, TimeUnit.SECONDS); } // executor.scheduleAtFixedRate(this::processQueue, 0, 1, TimeUnit.SECONDS); } public void enqueue(Request request) { log.info("QUEUE > ADD: {}", request); queue.offer(request); } private void processQueue(int workerId) { Request request = queue.poll(); log.info("[worker-{}] QUEUE > CHECK", workerId); if (request == null) { return; } log.info("[worker-{}__jobId-{}] QUEUE > PROCESS START", workerId, request.getId()); try { this.apiService.executeApi(request); } catch (Exception e) { e.printStackTrace(); } finally { log.info("[worker-{}__jobId-{}] QUEUE > PROCESS END", workerId, request.getId()); } } @Data @ToString public static class Request { int id; int runTime; } }
// Queue101Application import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ThreadLocalRandom; @RestController @SpringBootApplication public class Queue101Application { @Autowired BlockingQueueService blockingQueueService; private int count = 0; public static void main(String[] args) { SpringApplication.run(Queue101Application.class, args); } @GetMapping("/trigger") public String trigger() { for (int i = 0; i < 100; i++) { BlockingQueueService.Request request = new BlockingQueueService.Request(); int randomNumber = ThreadLocalRandom.current().nextInt(1,2); request.setId(count); request.setRunTime(randomNumber*1000); count++; blockingQueueService.enqueue(request); } return "SUCCESS"; } }
Test
- Trigger queue: http://localhost:8080/trigger
- Log
... 2025-04-17T21:22:44.409+09:00 INFO 88153 --- [queue101] [nio-8080-exec-1] o.h.queue101.BlockingQueueService : QUEUE > ADD: BlockingQueueService.Request(id=99, runTime=1000) 2025-04-17T21:22:45.799+09:00 INFO 88153 --- [queue101] [pool-2-thread-1] o.h.queue101.BlockingQueueService : [worker-1] QUEUE > CHECK 2025-04-17T21:22:45.799+09:00 INFO 88153 --- [queue101] [pool-2-thread-1] o.h.queue101.BlockingQueueService : [worker-1__jobId-0] QUEUE > PROCESS START 2025-04-17T21:22:46.799+09:00 INFO 88153 --- [queue101] [pool-2-thread-1] o.h.queue101.BlockingQueueService : [worker-1__jobId-0] QUEUE > PROCESS END 2025-04-17T21:22:47.800+09:00 INFO 88153 --- [queue101] [pool-2-thread-1] o.h.queue101.BlockingQueueService : [worker-1] QUEUE > CHECK 2025-04-17T21:22:47.801+09:00 INFO 88153 --- [queue101] [pool-2-thread-1] o.h.queue101.BlockingQueueService : [worker-1__jobId-1] QUEUE > PROCESS START 2025-04-17T21:22:48.806+09:00 INFO 88153 --- [queue101] [pool-2-thread-1] o.h.queue101.BlockingQueueService : [worker-1__jobId-1] QUEUE > PROCESS END ...
Top comments (0)