diff --git a/src/main/java/mate/academy/AsyncRequestProcessor.java b/src/main/java/mate/academy/AsyncRequestProcessor.java index ee5eea1..ebb4f30 100644 --- a/src/main/java/mate/academy/AsyncRequestProcessor.java +++ b/src/main/java/mate/academy/AsyncRequestProcessor.java @@ -1,16 +1,46 @@ package mate.academy; +import java.util.Map; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; public class AsyncRequestProcessor { + private final Executor executor; + private final Map cache = new ConcurrentHashMap<>(); + private final Map> inFlight = + new ConcurrentHashMap<>(); + public AsyncRequestProcessor(Executor executor) { this.executor = executor; } public CompletableFuture processRequest(String userId) { - return null; + UserData cached = cache.get(userId); + if (cached != null) { + return CompletableFuture.completedFuture(cached); + } + + return inFlight.computeIfAbsent(userId, id -> + CompletableFuture.supplyAsync(() -> { + simulateDelay(); + return new UserData(id, "Details for " + id); + }, executor).whenComplete((result, error) -> { + inFlight.remove(id); + if (error == null) { + cache.put(id, result); + } + }) + ); + } + + private void simulateDelay() { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } } } diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java index a3c9b9e..80dcc34 100644 --- a/src/main/java/mate/academy/Main.java +++ b/src/main/java/mate/academy/Main.java @@ -1,26 +1,21 @@ package mate.academy; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; public class Main { public static void main(String[] args) { - // Feel free to play with AsyncRequestProcessor in this main method if you want - ExecutorService executor = null; // Provide implementation that fits your needs - AsyncRequestProcessor asyncRequestProcessor = new AsyncRequestProcessor(executor); + ExecutorService executor = Executors.newFixedThreadPool(4); + AsyncRequestProcessor processor = new AsyncRequestProcessor(executor); - // Simulating multiple concurrent requests - String[] userIds = {"user1", "user2", "user3", "user1"}; // Note: "user1" is repeated - CompletableFuture[] futures = new CompletableFuture[userIds.length]; + String[] userIds = {"user1", "user2", "user3", "user1"}; - for (int i = 0; i < userIds.length; i++) { - String userId = userIds[i]; - futures[i] = asyncRequestProcessor.processRequest(userId) - .thenAccept(userData -> System.out.println("Processed: " + userData)); + for (String userId : userIds) { + processor.processRequest(userId) + .thenAccept(result -> + System.out.println("Processed: " + result)); } - // Wait for all futures to complete - CompletableFuture.allOf(futures).join(); executor.shutdown(); } } diff --git a/src/main/java/mate/academy/UserData.java b/src/main/java/mate/academy/UserData.java index ef80432..fcd932a 100644 --- a/src/main/java/mate/academy/UserData.java +++ b/src/main/java/mate/academy/UserData.java @@ -1,5 +1,4 @@ package mate.academy; public record UserData(String userId, String details) { - }