Skip to content

Develop a Java application that processes user requests asynchronousl…#248

Open
ddryzhov wants to merge 1 commit into
mate-academy:mainfrom
ddryzhov:feat/request-processing
Open

Develop a Java application that processes user requests asynchronousl…#248
ddryzhov wants to merge 1 commit into
mate-academy:mainfrom
ddryzhov:feat/request-processing

Conversation

@ddryzhov

Copy link
Copy Markdown

…y using CompletableFuture and caches the results in a Map interface

…y using CompletableFuture and caches the results in a Map interface
Copilot AI review requested due to automatic review settings March 29, 2026 19:27

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ConcurrentHashMap cache for UserData keyed by userId.
  • Implemented processRequest to return cached results immediately or compute them asynchronously on the provided Executor.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +17 to +20
UserData cached = cache.get(userId);
if (cached != null) {
return CompletableFuture.completedFuture(cached);
}

Copilot AI Mar 29, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +23
UserData cached = cache.get(userId);
if (cached != null) {
return CompletableFuture.completedFuture(cached);
}

return CompletableFuture.supplyAsync(() -> {
try {

Copilot AI Mar 29, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +23 to +27
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}

Copilot AI Mar 29, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +10 to 13
private final Map<String, UserData> cache = new ConcurrentHashMap<>();

public AsyncRequestProcessor(Executor executor) {
this.executor = executor;

Copilot AI Mar 29, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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;

Copilot uses AI. Check for mistakes.

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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! ✨

Footnotes

  1. Rate AI review example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants