From 1b5ced323edbc81b2618ac90c86a8376c6706822 Mon Sep 17 00:00:00 2001 From: larsu Date: Mon, 16 Feb 2026 15:40:29 +0400 Subject: [PATCH 1/3] implemented cacheable AsyncRequestProcessor --- .../java/mate/academy/AsyncRequestProcessor.java | 15 ++++++++++++++- src/main/java/mate/academy/Main.java | 7 +++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/main/java/mate/academy/AsyncRequestProcessor.java b/src/main/java/mate/academy/AsyncRequestProcessor.java index ee5eea1..ea51afc 100644 --- a/src/main/java/mate/academy/AsyncRequestProcessor.java +++ b/src/main/java/mate/academy/AsyncRequestProcessor.java @@ -1,16 +1,29 @@ 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 Map cache; public AsyncRequestProcessor(Executor executor) { this.executor = executor; + cache = new ConcurrentHashMap<>(); } public CompletableFuture processRequest(String userId) { - return null; + return CompletableFuture.supplyAsync(() -> cache.computeIfAbsent(userId, id -> { + try { + UserData userData = new UserData(userId, "Details for " + userId); + Thread.sleep(1000); + return userData; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException("Request for " + userId + " was interrupted"); + } + }), executor); } } diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java index a3c9b9e..2320eba 100644 --- a/src/main/java/mate/academy/Main.java +++ b/src/main/java/mate/academy/Main.java @@ -2,14 +2,14 @@ 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 + ExecutorService executor = Executors + .newFixedThreadPool(3); AsyncRequestProcessor asyncRequestProcessor = new AsyncRequestProcessor(executor); - // Simulating multiple concurrent requests String[] userIds = {"user1", "user2", "user3", "user1"}; // Note: "user1" is repeated CompletableFuture[] futures = new CompletableFuture[userIds.length]; @@ -19,7 +19,6 @@ public static void main(String[] args) { .thenAccept(userData -> System.out.println("Processed: " + userData)); } - // Wait for all futures to complete CompletableFuture.allOf(futures).join(); executor.shutdown(); } From 6d20f06f797104b0bcb99c0ee76ef5e483500476 Mon Sep 17 00:00:00 2001 From: larsu Date: Mon, 16 Feb 2026 16:13:34 +0400 Subject: [PATCH 2/3] fixed some issues --- src/main/java/mate/academy/AsyncRequestProcessor.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/mate/academy/AsyncRequestProcessor.java b/src/main/java/mate/academy/AsyncRequestProcessor.java index ea51afc..abf6426 100644 --- a/src/main/java/mate/academy/AsyncRequestProcessor.java +++ b/src/main/java/mate/academy/AsyncRequestProcessor.java @@ -15,15 +15,21 @@ public AsyncRequestProcessor(Executor executor) { } public CompletableFuture processRequest(String userId) { - return CompletableFuture.supplyAsync(() -> cache.computeIfAbsent(userId, id -> { + UserData cached = cache.get(userId); + if (cached != null) { + return CompletableFuture.completedFuture(cached); + } + + return CompletableFuture.supplyAsync(() -> { try { UserData userData = new UserData(userId, "Details for " + userId); Thread.sleep(1000); + cache.putIfAbsent(userId, userData); return userData; } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException("Request for " + userId + " was interrupted"); } - }), executor); + }, executor); } } From 99f5d582a0912be6472ee8bb5ee958931b894722 Mon Sep 17 00:00:00 2001 From: larsu Date: Mon, 16 Feb 2026 16:56:20 +0400 Subject: [PATCH 3/3] fixed some more issues --- .../mate/academy/AsyncRequestProcessor.java | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/main/java/mate/academy/AsyncRequestProcessor.java b/src/main/java/mate/academy/AsyncRequestProcessor.java index abf6426..12bbd1a 100644 --- a/src/main/java/mate/academy/AsyncRequestProcessor.java +++ b/src/main/java/mate/academy/AsyncRequestProcessor.java @@ -7,7 +7,7 @@ public class AsyncRequestProcessor { private final Executor executor; - private Map cache; + private Map> cache; public AsyncRequestProcessor(Executor executor) { this.executor = executor; @@ -15,21 +15,17 @@ public AsyncRequestProcessor(Executor executor) { } public CompletableFuture processRequest(String userId) { - UserData cached = cache.get(userId); - if (cached != null) { - return CompletableFuture.completedFuture(cached); - } - - return CompletableFuture.supplyAsync(() -> { - try { - UserData userData = new UserData(userId, "Details for " + userId); - Thread.sleep(1000); - cache.putIfAbsent(userId, userData); - return userData; - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new RuntimeException("Request for " + userId + " was interrupted"); - } - }, executor); + return cache.computeIfAbsent(userId, id -> + CompletableFuture.supplyAsync(() -> { + try { + UserData userData = new UserData(userId, "Details for " + id); + Thread.sleep(1000); + return userData; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException("Request for " + id + " was interrupted"); + } + },executor) + ); } }