diff --git a/cffu-bom/pom.xml b/cffu-bom/pom.xml index cd9e4b4d6..151e165d9 100644 --- a/cffu-bom/pom.xml +++ b/cffu-bom/pom.xml @@ -154,7 +154,7 @@ org.sonatype.central central-publishing-maven-plugin - 0.9.0 + 0.10.0 true central diff --git a/cffu-core/src/main/java/io/foldright/cffu2/ConcurrencyLimitExecutor.java b/cffu-core/src/main/java/io/foldright/cffu2/ConcurrencyLimitExecutor.java index 810c52c9b..981cdb706 100644 --- a/cffu-core/src/main/java/io/foldright/cffu2/ConcurrencyLimitExecutor.java +++ b/cffu-core/src/main/java/io/foldright/cffu2/ConcurrencyLimitExecutor.java @@ -7,7 +7,6 @@ import java.util.ArrayDeque; import java.util.Deque; import java.util.concurrent.Executor; -import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -58,10 +57,6 @@ public void execute(Runnable command) { // so no need to declare it as type AtomicBoolean for thread safety. final boolean[] locking = {true}; try { - if (syncRunnerCount >= maxConcurrency) throw new RejectedExecutionException("reject new task:" - + " synchronous running task(s) (i.e. CallerRunsPolicy) already occupy" - + " all concurrency slot(s) of " + ConcurrencyLimitExecutor.this); - queue.add(command); if (workerCount >= maxConcurrency) return; @@ -93,13 +88,19 @@ private void syncRun() { try { command.run(); } finally { + boolean scheduleAsyncWorker = false; lock.lock(); try { workerCount--; syncRunnerCount--; + if (!queue.isEmpty() && workerCount < maxConcurrency) { + incrementWorkerCount(); + scheduleAsyncWorker = true; + } } finally { lock.unlock(); } + if (scheduleAsyncWorker) submitAsyncWorkerAfterSyncRun(); } } @@ -154,6 +155,20 @@ private void asyncWork() { } } + private void submitAsyncWorkerAfterSyncRun() { + try { + executor.execute(this::asyncWork); + } catch (Throwable e) { + lock.lock(); + try { + workerCount--; + } finally { + lock.unlock(); + } + logUncaughtException(ERROR, super.toString() + "#submitAsyncWorkerAfterSyncRun", e); + } + } + @GuardedBy("lock") private void incrementWorkerCount() { workerCount++; diff --git a/cffu-core/src/test/java/io/foldright/cffu2/ConcurrencyLimitExecutorTest.kt b/cffu-core/src/test/java/io/foldright/cffu2/ConcurrencyLimitExecutorTest.kt index b0b1f9097..c3a40d51f 100644 --- a/cffu-core/src/test/java/io/foldright/cffu2/ConcurrencyLimitExecutorTest.kt +++ b/cffu-core/src/test/java/io/foldright/cffu2/ConcurrencyLimitExecutorTest.kt @@ -157,12 +157,10 @@ class ConcurrencyLimitExecutorTest : FunSpec({ } /** - * ❗❗ TODO: Due to the limitation in the current ConcurrencyLimitExecutor implementation, - * if all tasks execute synchronously, - * - the remaining tasks in the work queue cannot be executed! - * - the task execution is only triggered by task submission. + * Regression test: when all submitted tasks execute synchronously at the base executor, + * queued tasks must still be drained after synchronous runners complete. */ - test("sync execution at MoreExecutors.directExecutor(), multi-threaded submission").config(enabled = false) { + test("sync execution at MoreExecutors.directExecutor(), multi-threaded submission") { val concurrencyLimitExecutor = ConcurrencyLimitExecutor(3, MoreExecutors.directExecutor()) val concurrencyChecker = ConcurrencyChecker(3) diff --git a/demos/pom.xml b/demos/pom.xml index adf0a4bed..412691246 100644 --- a/demos/pom.xml +++ b/demos/pom.xml @@ -14,7 +14,7 @@ ${project.build.sourceEncoding} true - 2.3.0 + 2.3.10 ${maven.compiler.source} @@ -22,7 +22,7 @@ - 5.14.1 + 5.14.2 @@ -114,7 +114,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.14.1 + 3.15.0 diff --git a/pom.xml b/pom.xml index 1485b55f4..a475686e1 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ 3.0.2 26.0.2-1 - 2.3.0 + 2.3.10 2.0.17 2.25.3 @@ -90,7 +90,7 @@ 33.5.0-jre - 5.14.1 + 5.14.2 5.9.1 @@ -148,7 +148,7 @@ org.assertj assertj-bom - 3.27.6 + 3.27.7 pom import @@ -392,7 +392,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.14.1 + 3.15.0 @@ -469,7 +469,7 @@ org.apache.maven.plugins maven-dependency-plugin - 3.9.0 + 3.10.0 io.github.git-commit-id @@ -1090,7 +1090,7 @@ org.sonatype.central central-publishing-maven-plugin - 0.9.0 + 0.10.0 true central