From 300af1edc3c4f8ade4d5a28586fc6c8112ce77ee Mon Sep 17 00:00:00 2001 From: John Niang Date: Thu, 2 Oct 2025 18:22:25 +0800 Subject: [PATCH] Fix recursive update issue in concurrent map for thumbnail generation (#7789) #### What type of PR is this? /kind bug /area core /milestone 2.22.x #### What this PR does / why we need it: This PR fixes recursive update issue in concurrent map for thumbnail generation. ```java java.lang.IllegalStateException: Recursive update at java.base/java.util.concurrent.ConcurrentHashMap.replaceNode(Unknown Source) ~[na:na] ``` #### Does this PR introduce a user-facing change? ```release-note None ``` --- .../app/core/attachment/endpoint/ThumbnailRouters.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/application/src/main/java/run/halo/app/core/attachment/endpoint/ThumbnailRouters.java b/application/src/main/java/run/halo/app/core/attachment/endpoint/ThumbnailRouters.java index c4c0f13a3..e6e9507f8 100644 --- a/application/src/main/java/run/halo/app/core/attachment/endpoint/ThumbnailRouters.java +++ b/application/src/main/java/run/halo/app/core/attachment/endpoint/ThumbnailRouters.java @@ -149,8 +149,7 @@ class ThumbnailRouters { private Mono generateThumbnail( String filename, Path attachmentPath, Path thumbnailPath, ThumbnailSize size ) { - return Mono.fromFuture(() -> inProgress.computeIfAbsent(filename, - f -> + return Mono.fromFuture(() -> inProgress.computeIfAbsent(filename, f -> CompletableFuture.supplyAsync(() -> generateThumbnail( attachmentPath, thumbnailPath, size ), @@ -160,8 +159,10 @@ class ThumbnailRouters { DEFAULT_GENERATION_TIMEOUT_SECONDS, TimeUnit.SECONDS ) - .whenComplete((p, t) -> inProgress.remove(filename)) - ), + ) + // Remove the entry from the map when the task is complete outside the + // computeIfAbsent to prevent the recursive update + .whenComplete((p, t) -> inProgress.remove(filename)), // We don't want to cancel the thumbnail generation task // when some requests are cancelled true