Develop a Java application that processes user requests asynchronousl…#248
Develop a Java application that processes user requests asynchronousl…#248ddryzhov wants to merge 1 commit into
Conversation
…y using CompletableFuture and caches the results in a Map interface
There was a problem hiding this comment.
Pull request overview
Implements asynchronous request processing in AsyncRequestProcessor using CompletableFuture, and adds an in-memory cache to reuse previously computed UserData results.
Changes:
- Added a thread-safe
ConcurrentHashMapcache forUserDatakeyed byuserId. - Implemented
processRequestto return cached results immediately or compute them asynchronously on the providedExecutor.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| UserData cached = cache.get(userId); | ||
| if (cached != null) { | ||
| return CompletableFuture.completedFuture(cached); | ||
| } |
There was a problem hiding this comment.
The new caching behavior isn't covered by tests: there are no assertions that a second call with the same userId returns a completed future immediately (or avoids repeating the simulated delay/work). Adding a test for the cached path would help prevent regressions when changing the caching strategy (e.g., to cache in-flight futures).
| UserData cached = cache.get(userId); | ||
| if (cached != null) { | ||
| return CompletableFuture.completedFuture(cached); | ||
| } | ||
|
|
||
| return CompletableFuture.supplyAsync(() -> { | ||
| try { |
There was a problem hiding this comment.
cache.get() + subsequent async computation allows multiple concurrent calls for the same userId to miss the cache and perform duplicate work before cache.put() happens. Consider caching an in-flight CompletableFuture<UserData> via computeIfAbsent, or at least using putIfAbsent/double-check to ensure only one computation populates the cache for a given key.
| try { | ||
| Thread.sleep(1000); | ||
| } catch (InterruptedException e) { | ||
| Thread.currentThread().interrupt(); | ||
| } |
There was a problem hiding this comment.
After catching InterruptedException, the code re-interrupts the thread but then continues and returns a "successful" UserData. This can lead to completing the future with partial/invalid work when the task was asked to stop. Prefer completing the CompletableFuture exceptionally (e.g., by rethrowing via CompletionException) or returning early when interrupted.
| private final Map<String, UserData> cache = new ConcurrentHashMap<>(); | ||
|
|
||
| public AsyncRequestProcessor(Executor executor) { | ||
| this.executor = executor; |
There was a problem hiding this comment.
The cache is unbounded and will grow for every distinct userId, which can lead to memory growth over time in long-running processes. If this class is intended for production-like usage, consider an eviction policy (size/TTL) or allowing the cache implementation to be injected so callers can choose bounded caching.
| private final Map<String, UserData> cache = new ConcurrentHashMap<>(); | |
| public AsyncRequestProcessor(Executor executor) { | |
| this.executor = executor; | |
| private final Map<String, UserData> cache; | |
| public AsyncRequestProcessor(Executor executor) { | |
| this(executor, new ConcurrentHashMap<>()); | |
| } | |
| public AsyncRequestProcessor(Executor executor, Map<String, UserData> cache) { | |
| this.executor = executor; | |
| this.cache = cache; |
mateacademy-ai-mentor
left a comment
There was a problem hiding this comment.
Review Summary
Excellent work on this task! Your solution is being approved. You have correctly implemented the AsyncRequestProcessor using CompletableFuture for asynchronous processing and ConcurrentHashMap for thread-safe caching, fulfilling all the requirements perfectly. The code is clean, and the logic for checking the cache before processing a request is spot on. The failed check you might see is related to our CI environment and not your code, so you can safely ignore it. Keep up the great work!
✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨
…y using CompletableFuture and caches the results in a Map interface