From f9fd91244acb022592b9758b1b90b8d75798d07f Mon Sep 17 00:00:00 2001 From: Nathan Rauh Date: Fri, 4 Oct 2024 09:50:17 -0500 Subject: [PATCH 1/8] Issue #27306 untimed invokeAny/All to never run inline when virtual=true --- .../OSGI-INF/l10n/metatype.properties | 21 +++++++++++++++--- .../com/ibm/ws/threading/PolicyExecutor.java | 7 ------ .../internal/PolicyExecutorImpl.java | 22 ++++++++----------- ...ManagedExecutorResourceFactoryBuilder.java | 7 +++--- ...heduledExecutorResourceFactoryBuilder.java | 7 +++--- 5 files changed, 33 insertions(+), 31 deletions(-) diff --git a/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties b/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties index 41eb3c59755..1b8e5952be0 100644 --- a/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties +++ b/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties @@ -30,9 +30,24 @@ max=Maximum concurrency max.desc=Specifies the maximum number of tasks that can run simultaneously. The default is Integer.MAX_VALUE. Maximum concurrency can be updated while tasks are in progress. If the maximum concurrency is reduced below the number of concurrently running tasks, the update goes into effect gradually as in-progress tasks complete, rather than canceling them. maxPolicy=Maximum policy -maxPolicy.desc=Indicates whether to loosely or strictly enforce maximum concurrency for tasks that run on the task submitter's thread. Tasks can run on the task submitter's thread when using the untimed invokeAll method, or, if only invoking a single task, the untimed invokeAny method. If the run-if-queue-full attribute is configured, it is also possible for tasks to run the task submitter's thread when using the execute and submit methods. In all of these cases, this attribute determines whether or not running on the submitter's thread counts against the maximum concurrency. -maxPolicy.loose.desc=Maximum concurrency is loosely enforced. Tasks are allowed to run on the task submitter's thread without counting against maximum concurrency. -maxPolicy.strict.desc=Maximum concurrency is strictly enforced. Tasks that run on the task submitter's thread count towards maximum concurrency. This policy does not allow tasks to run on the task submitter's thread when already at maximum concurrency. +maxPolicy.desc=Indicates whether to loosely or strictly enforce maximum \ + concurrency for tasks that run on the task submitter's thread. If the \ + concurrency policy is not configured to run tasks on virtual threads, tasks can \ + run on the task submitter's thread when using the untimed invokeAll method, or, \ + if only invoking a single task, when using the untimed invokeAny method. \ + If the run-if-queue-full attribute is configured, it is also possible for tasks \ + to run the task submitter's thread when using the execute and submit methods. \ + In all of these cases, this attribute determines whether or not running on the \ + submitter's thread counts against the maximum concurrency. Completion stage \ + tasks that run inline do not count against the maximum concurrency regardless \ + of the maximum policy. +maxPolicy.loose.desc=Maximum concurrency is loosely enforced. \ + Tasks are allowed to run on the task submitter's thread without \ + counting against maximum concurrency. +maxPolicy.strict.desc=Maximum concurrency is strictly enforced. \ + Tasks that run on the task submitter's thread count towards maximum concurrency. \ + This policy does not allow tasks to run on the task submitter's thread when \ + already at maximum concurrency. maxQueueSize=Maximum queue size maxQueueSize.desc=Specifies the maximum number of tasks that can be in the queue waiting for execution. As tasks are started, canceled, or aborted, they are removed from the queue. When the queue is at capacity and another task is submitted, the behavior is determined by the maximum wait for enqueue and run-if-queue-full attributes. To ensure that a specific number of tasks can be queued within a short interval of time, use a maximum queue size that is at least as large as that amount. The default maximum queue size is Integer.MAX_VALUE. Maximum queue size can be updated while tasks are both in progress or queued for execution. If the maximum queue size is reduced below the current number of queued tasks, the update goes into effect gradually rather than automatically canceling the excess queued tasks. diff --git a/dev/com.ibm.ws.threading/src/com/ibm/ws/threading/PolicyExecutor.java b/dev/com.ibm.ws.threading/src/com/ibm/ws/threading/PolicyExecutor.java index ab3a6ae9c16..08d2de9ed92 100644 --- a/dev/com.ibm.ws.threading/src/com/ibm/ws/threading/PolicyExecutor.java +++ b/dev/com.ibm.ws.threading/src/com/ibm/ws/threading/PolicyExecutor.java @@ -51,13 +51,6 @@ public enum MaxPolicy { * This policy does not allow running on the submitter's thread if already at maximum concurrency. */ strict - - /* - * Leaving the policy unspecified indicates that the policy is to be chosen on a case-by-case basis - * based on whether the submitter thread is a virtual thread (try to avoid running on the submitter's thread) - * or a platform thread (use a policy of loose). - */ - // unspecified } /** diff --git a/dev/com.ibm.ws.threading/src/com/ibm/ws/threading/internal/PolicyExecutorImpl.java b/dev/com.ibm.ws.threading/src/com/ibm/ws/threading/internal/PolicyExecutorImpl.java index ac13e3c1af0..cb64e7c92e2 100644 --- a/dev/com.ibm.ws.threading/src/com/ibm/ws/threading/internal/PolicyExecutorImpl.java +++ b/dev/com.ibm.ws.threading/src/com/ibm/ws/threading/internal/PolicyExecutorImpl.java @@ -803,14 +803,12 @@ public List> invokeAll(Collection> boolean havePermit = false; boolean useCurrentThread; MaxPolicy policy = maxPolicy; - if (policy == MaxPolicy.loose) // can always run inline + if (virtual) // always run asynchronously on new virtual thread + useCurrentThread = false; + else if (policy == MaxPolicy.loose) // can always run inline useCurrentThread = true; - else if (policy == MaxPolicy.strict) // must acquire a permit to run inline + else // policy == MaxPolicy.strict // must acquire a permit to run inline useCurrentThread = havePermit = taskCount > 0 && maxConcurrencyConstraint.tryAcquire(); - else // can run inline on platform threads (loose); Never run inline on virtual threads - throw new UnsupportedOperationException("maxPolicy=null"); // currently unreachable, waiting for a pull that is blocked - // TODO: - // useCurrentThread = !(virtualThreadOps.isSupported() && virtualThreadOps.isVirtual(Thread.currentThread())); List> futures = new ArrayList>(taskCount); try { @@ -983,14 +981,12 @@ public T invokeAny(Collection> tasks, PolicyTaskCallba boolean havePermit = false; boolean useCurrentThread; MaxPolicy policy = maxPolicy; - if (policy == MaxPolicy.loose) // can always run inline + if (virtual) // always run asynchronously on new virtual thread + useCurrentThread = false; + else if (policy == MaxPolicy.loose) // can always run inline useCurrentThread = true; - else if (policy == MaxPolicy.strict) // must acquire a permit to run inline + else // policy == MaxPolicy.strict // must acquire a permit to run inline useCurrentThread = havePermit = maxConcurrencyConstraint.tryAcquire(); - else // can run inline on platform threads (loose); Never run inline on virtual threads - throw new UnsupportedOperationException("maxPolicy=null"); // currently unreachable, waiting for a pull that is blocked - // TODO: - // useCurrentThread = !(virtualThreadOps.isSupported() && virtualThreadOps.isVirtual(Thread.currentThread())); if (useCurrentThread) try { @@ -1538,7 +1534,7 @@ public void updateConfig(Map props) { long u_maxWaitForEnqueue = (Long) props.get("maxWaitForEnqueue"); boolean u_runIfQueueFull = (Boolean) props.get("runIfQueueFull"); long u_startTimeout = null == (v = props.get("startTimeout")) ? -1l : (Long) v; - boolean useVirtualThreads = null == (v = props.get("virtual")) ? false : (Boolean) v;; + boolean useVirtualThreads = null == (v = props.get("virtual")) ? false : (Boolean) v; // Validation that cannot be performed by metatype: if (useVirtualThreads && !virtualThreadOps.isSupported()) { diff --git a/dev/io.openliberty.concurrent.internal/src/io/openliberty/concurrent/internal/processor/ManagedExecutorResourceFactoryBuilder.java b/dev/io.openliberty.concurrent.internal/src/io/openliberty/concurrent/internal/processor/ManagedExecutorResourceFactoryBuilder.java index 9d0f6e8b756..b3457145b1b 100644 --- a/dev/io.openliberty.concurrent.internal/src/io/openliberty/concurrent/internal/processor/ManagedExecutorResourceFactoryBuilder.java +++ b/dev/io.openliberty.concurrent.internal/src/io/openliberty/concurrent/internal/processor/ManagedExecutorResourceFactoryBuilder.java @@ -219,11 +219,10 @@ else if (maxAsync != -1) // unbounded concurrencyPolicyProps.put("maxWaitForEnqueue", 0L); concurrencyPolicyProps.put("runIfQueueFull", false); - if (Boolean.TRUE.equals(virtual) && JavaInfo.majorVersion() >= 21) { // only available in Concurrency 3.1+ and Java 21+ + if (Boolean.TRUE.equals(virtual) && JavaInfo.majorVersion() >= 21) { + // only available in Concurrency 3.1+ and Java 21+ concurrencyPolicyProps.put("virtual", virtual); - // maxPolicy unspecified makes the policy conditional on whether or not the submitter thread is virtual - // TODO remove the following once unspecified is supported - concurrencyPolicyProps.put("maxPolicy", "loose"); + concurrencyPolicyProps.put("maxPolicy", "strict"); } else { if (Boolean.TRUE.equals(virtual)) Tr.info(tc, "CWWKC1217.no.virtual.threads", diff --git a/dev/io.openliberty.concurrent.internal/src/io/openliberty/concurrent/internal/processor/ManagedScheduledExecutorResourceFactoryBuilder.java b/dev/io.openliberty.concurrent.internal/src/io/openliberty/concurrent/internal/processor/ManagedScheduledExecutorResourceFactoryBuilder.java index fa78380d557..657345b5b01 100644 --- a/dev/io.openliberty.concurrent.internal/src/io/openliberty/concurrent/internal/processor/ManagedScheduledExecutorResourceFactoryBuilder.java +++ b/dev/io.openliberty.concurrent.internal/src/io/openliberty/concurrent/internal/processor/ManagedScheduledExecutorResourceFactoryBuilder.java @@ -222,11 +222,10 @@ else if (maxAsync != -1) // unbounded concurrencyPolicyProps.put("maxWaitForEnqueue", 0L); concurrencyPolicyProps.put("runIfQueueFull", false); - if (Boolean.TRUE.equals(virtual) && JavaInfo.majorVersion() >= 21) { // only available in Concurrency 3.1+ and Java 21+ + if (Boolean.TRUE.equals(virtual) && JavaInfo.majorVersion() >= 21) { + // only available in Concurrency 3.1+ and Java 21+ concurrencyPolicyProps.put("virtual", virtual); - // maxPolicy unspecified makes the policy conditional on whether or not the submitter thread is virtual - // TODO remove the following once unspecified is supported - concurrencyPolicyProps.put("maxPolicy", "loose"); + concurrencyPolicyProps.put("maxPolicy", "strict"); } else { if (Boolean.TRUE.equals(virtual)) Tr.info(tc, "CWWKC1217.no.virtual.threads", From 0126ae0dd178331f605ff230d13d6474c2eaef35 Mon Sep 17 00:00:00 2001 From: Nathan Rauh Date: Fri, 4 Oct 2024 09:51:03 -0500 Subject: [PATCH 2/8] Issue #27306 test for untimed invokeAny and invokeAll using virtual threads --- .../web/Concurrency31TestServlet.java | 118 +++++++++++++++++- 1 file changed, 115 insertions(+), 3 deletions(-) diff --git a/dev/com.ibm.ws.concurrent_fat_jakarta_11/test-applications/Concurrency31TestWeb/src/test/jakarta/concurrency31/web/Concurrency31TestServlet.java b/dev/com.ibm.ws.concurrent_fat_jakarta_11/test-applications/Concurrency31TestWeb/src/test/jakarta/concurrency31/web/Concurrency31TestServlet.java index 78d7ad6f13a..7c5d33a9d1b 100644 --- a/dev/com.ibm.ws.concurrent_fat_jakarta_11/test-applications/Concurrency31TestWeb/src/test/jakarta/concurrency31/web/Concurrency31TestServlet.java +++ b/dev/com.ibm.ws.concurrent_fat_jakarta_11/test-applications/Concurrency31TestWeb/src/test/jakarta/concurrency31/web/Concurrency31TestServlet.java @@ -16,6 +16,7 @@ import static jakarta.enterprise.concurrent.ContextServiceDefinition.APPLICATION; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; import static org.junit.Assert.fail; import java.time.ZoneId; @@ -25,6 +26,7 @@ import java.util.List; import java.util.Set; import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; @@ -253,7 +255,119 @@ public void testTimedInvokeAnyOnVirtualThreads() throws Exception { assertEquals(Boolean.TRUE, Thread.class.getMethod("isVirtual").invoke(thread)); } - // TODO after the workaround is removed, write: public void testUntimedInvokeAllOnVirtualThreads() throws Exception { + /** + * Use ManagedExecutorDefinition with virtual=true to submit multiple task + * to run on a virtual thread via the untimed invokeAll method. + */ + @Test + public void testUntimedInvokeAllOnVirtualThreads() throws Exception { + Callable task = () -> { + InitialContext.doLookup("java:comp/env/TestEntry"); + return Thread.currentThread(); + }; + + ManagedExecutorService executor = InitialContext // + .doLookup("java:module/concurrent/virtual-executor"); + + List> futures = executor.invokeAll(List.of(task, task, task)); + + assertEquals(futures.toString(), 3, futures.size()); + + Set uniqueThreads = new HashSet(); + uniqueThreads.add(Thread.currentThread()); + + Thread thread; + assertNotNull(thread = futures.get(0).get(TIMEOUT_NS, TimeUnit.NANOSECONDS)); + assertEquals(Boolean.TRUE, + Thread.class.getMethod("isVirtual").invoke(thread)); + uniqueThreads.add(thread); + + assertNotNull(thread = futures.get(1).get(TIMEOUT_NS, TimeUnit.NANOSECONDS)); + assertEquals(Boolean.TRUE, + Thread.class.getMethod("isVirtual").invoke(thread)); + uniqueThreads.add(thread); + + assertNotNull(thread = futures.get(2).get(TIMEOUT_NS, TimeUnit.NANOSECONDS)); + assertEquals(Boolean.TRUE, + Thread.class.getMethod("isVirtual").invoke(thread)); + uniqueThreads.add(thread); + + assertEquals(uniqueThreads.toString(), 4, uniqueThreads.size()); + uniqueThreads.clear(); + + // run from a virtual thread: + CompletableFuture>> ff = new CompletableFuture<>(); + ManagedThreadFactory threadFactory = InitialContext // + .doLookup("java:module/concurrent/virtual-thread-factory"); + threadFactory.newThread(() -> { + try { + uniqueThreads.add(Thread.currentThread()); + ff.complete(executor.invokeAll(List.of(task, task, task))); + } catch (Throwable x) { + ff.completeExceptionally(x); + } + }).start(); + + futures = ff.get(TIMEOUT_NS, TimeUnit.NANOSECONDS); + + assertEquals(futures.toString(), 3, futures.size()); + + assertNotNull(thread = futures.get(0).get(TIMEOUT_NS, TimeUnit.NANOSECONDS)); + assertEquals(Boolean.TRUE, + Thread.class.getMethod("isVirtual").invoke(thread)); + uniqueThreads.add(thread); + + assertNotNull(thread = futures.get(1).get(TIMEOUT_NS, TimeUnit.NANOSECONDS)); + assertEquals(Boolean.TRUE, + Thread.class.getMethod("isVirtual").invoke(thread)); + uniqueThreads.add(thread); + + assertNotNull(thread = futures.get(2).get(TIMEOUT_NS, TimeUnit.NANOSECONDS)); + assertEquals(Boolean.TRUE, + Thread.class.getMethod("isVirtual").invoke(thread)); + uniqueThreads.add(thread); + + assertEquals(uniqueThreads.toString(), 4, uniqueThreads.size()); + } + + /** + * Use ManagedExecutorDefinition with virtual=true to submit a single task + * to run on a virtual thread via the untimed invokeAny method. + */ + @Test + public void testUntimedInvokeAnyOneOnVirtualThread() throws Exception { + Callable anyTask = () -> { + InitialContext.doLookup("java:comp/env/TestEntry"); + return Thread.currentThread(); + }; + + ManagedExecutorService executor = InitialContext // + .doLookup("java:module/concurrent/virtual-executor"); + + Thread thread = executor.invokeAny(List.of(anyTask)); + + assertNotSame(Thread.currentThread(), thread); // does not run inline + assertEquals(Boolean.TRUE, + Thread.class.getMethod("isVirtual").invoke(thread)); + + // run from a virtual thread: + CompletableFuture futureThread = new CompletableFuture<>(); + ManagedThreadFactory threadFactory = InitialContext // + .doLookup("java:module/concurrent/virtual-thread-factory"); + Thread newThread = threadFactory.newThread(() -> { + try { + futureThread.complete(executor.invokeAny(List.of(anyTask))); + } catch (Throwable x) { + futureThread.completeExceptionally(x); + } + }); + newThread.start(); + + thread = futureThread.get(TIMEOUT_NS, TimeUnit.NANOSECONDS); + assertNotSame(newThread, thread); // does not run inline + assertEquals(Boolean.TRUE, + Thread.class.getMethod("isVirtual").invoke(thread)); + } /** * Use ManagedExecutorDefinition with virtual=true to submit multiple tasks to run on virtual threads, @@ -282,8 +396,6 @@ public void testUntimedInvokeAnyOnVirtualThreads() throws Exception { assertEquals(Boolean.TRUE, Thread.class.getMethod("isVirtual").invoke(thread)); } - // TODO after the workaround is removed, write: public void testUntimedInvokeAnyOneOnVirtualThread() throws Exception { - /** * Use a managed-executor from the application.xml deployment descriptor with * virtual=true to request that tasks run on virtual threads. From 773d42f04c90667fd3fcb361b8143cb78e60e778 Mon Sep 17 00:00:00 2001 From: Nathan Rauh Date: Fri, 4 Oct 2024 15:10:04 -0500 Subject: [PATCH 3/8] Update dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties Co-authored-by: David Mueller <48686014+dmuelle@users.noreply.github.com> --- .../resources/OSGI-INF/l10n/metatype.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties b/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties index 1b8e5952be0..cc48032deee 100644 --- a/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties +++ b/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties @@ -35,7 +35,7 @@ maxPolicy.desc=Indicates whether to loosely or strictly enforce maximum \ concurrency policy is not configured to run tasks on virtual threads, tasks can \ run on the task submitter's thread when using the untimed invokeAll method, or, \ if only invoking a single task, when using the untimed invokeAny method. \ - If the run-if-queue-full attribute is configured, it is also possible for tasks \ + If the run-if-queue-full attribute is configured, tasks can also\ to run the task submitter's thread when using the execute and submit methods. \ In all of these cases, this attribute determines whether or not running on the \ submitter's thread counts against the maximum concurrency. Completion stage \ From 70788280c0ee3e3ece2b3bd6b785494d499f2b54 Mon Sep 17 00:00:00 2001 From: Nathan Rauh Date: Fri, 4 Oct 2024 15:10:40 -0500 Subject: [PATCH 4/8] Update dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties Co-authored-by: David Mueller <48686014+dmuelle@users.noreply.github.com> --- .../resources/OSGI-INF/l10n/metatype.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties b/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties index cc48032deee..ac7aec38ddb 100644 --- a/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties +++ b/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties @@ -36,7 +36,7 @@ maxPolicy.desc=Indicates whether to loosely or strictly enforce maximum \ run on the task submitter's thread when using the untimed invokeAll method, or, \ if only invoking a single task, when using the untimed invokeAny method. \ If the run-if-queue-full attribute is configured, tasks can also\ - to run the task submitter's thread when using the execute and submit methods. \ + run on the task submitter's thread when using the execute and submit methods. \ In all of these cases, this attribute determines whether or not running on the \ submitter's thread counts against the maximum concurrency. Completion stage \ tasks that run inline do not count against the maximum concurrency regardless \ From d62de52405d0c37003977a7a959aad2aaaaacfae Mon Sep 17 00:00:00 2001 From: Nathan Rauh Date: Fri, 4 Oct 2024 15:10:56 -0500 Subject: [PATCH 5/8] Update dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties Co-authored-by: David Mueller <48686014+dmuelle@users.noreply.github.com> --- .../resources/OSGI-INF/l10n/metatype.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties b/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties index ac7aec38ddb..85011332385 100644 --- a/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties +++ b/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties @@ -37,7 +37,7 @@ maxPolicy.desc=Indicates whether to loosely or strictly enforce maximum \ if only invoking a single task, when using the untimed invokeAny method. \ If the run-if-queue-full attribute is configured, tasks can also\ run on the task submitter's thread when using the execute and submit methods. \ - In all of these cases, this attribute determines whether or not running on the \ + In all of these cases, this attribute determines whether running on the \ submitter's thread counts against the maximum concurrency. Completion stage \ tasks that run inline do not count against the maximum concurrency regardless \ of the maximum policy. From 97ef5c3ae43db369e4210b8e5a634652844e05c7 Mon Sep 17 00:00:00 2001 From: Nathan Rauh Date: Fri, 4 Oct 2024 15:11:05 -0500 Subject: [PATCH 6/8] Update dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties Co-authored-by: David Mueller <48686014+dmuelle@users.noreply.github.com> --- .../resources/OSGI-INF/l10n/metatype.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties b/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties index 85011332385..543970e6057 100644 --- a/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties +++ b/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties @@ -39,7 +39,7 @@ maxPolicy.desc=Indicates whether to loosely or strictly enforce maximum \ run on the task submitter's thread when using the execute and submit methods. \ In all of these cases, this attribute determines whether running on the \ submitter's thread counts against the maximum concurrency. Completion stage \ - tasks that run inline do not count against the maximum concurrency regardless \ + tasks that run inline do not count against the maximum concurrency, regardless \ of the maximum policy. maxPolicy.loose.desc=Maximum concurrency is loosely enforced. \ Tasks are allowed to run on the task submitter's thread without \ From 4516a85ca6e23e937040eebc9eb9c4978a32c99d Mon Sep 17 00:00:00 2001 From: Nathan Rauh Date: Fri, 4 Oct 2024 15:23:07 -0500 Subject: [PATCH 7/8] Address review comment --- .../resources/OSGI-INF/l10n/metatype.properties | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties b/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties index 543970e6057..05e146622fd 100644 --- a/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties +++ b/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties @@ -32,11 +32,12 @@ max.desc=Specifies the maximum number of tasks that can run simultaneously. The maxPolicy=Maximum policy maxPolicy.desc=Indicates whether to loosely or strictly enforce maximum \ concurrency for tasks that run on the task submitter's thread. If the \ - concurrency policy is not configured to run tasks on virtual threads, tasks can \ - run on the task submitter's thread when using the untimed invokeAll method, or, \ - if only invoking a single task, when using the untimed invokeAny method. \ - If the run-if-queue-full attribute is configured, tasks can also\ - run on the task submitter's thread when using the execute and submit methods. \ + concurrency policy is not configured to run tasks on virtual threads, the \ + invokeAll and invokeAny methods can sometimes run tasks on the task submitter's \ + thread. This happens when you use the untimed invokeAll method, or, \ + if you only supply a single task, when you use the untimed invokeAny method. \ + If the run-if-queue-full attribute is configured, tasks can also \ + run on the task submitter's thread when you use the execute and submit methods. \ In all of these cases, this attribute determines whether running on the \ submitter's thread counts against the maximum concurrency. Completion stage \ tasks that run inline do not count against the maximum concurrency, regardless \ From a632d658ab59364b29c888601511c93b106f7cf9 Mon Sep 17 00:00:00 2001 From: Nathan Rauh Date: Fri, 4 Oct 2024 15:36:05 -0500 Subject: [PATCH 8/8] Follow up review comment --- .../resources/OSGI-INF/l10n/metatype.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties b/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties index 05e146622fd..6cb26f56819 100644 --- a/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties +++ b/dev/com.ibm.ws.concurrency.policy/resources/OSGI-INF/l10n/metatype.properties @@ -34,7 +34,7 @@ maxPolicy.desc=Indicates whether to loosely or strictly enforce maximum \ concurrency for tasks that run on the task submitter's thread. If the \ concurrency policy is not configured to run tasks on virtual threads, the \ invokeAll and invokeAny methods can sometimes run tasks on the task submitter's \ - thread. This happens when you use the untimed invokeAll method, or, \ + thread. This situation happens when you use the untimed invokeAll method, or, \ if you only supply a single task, when you use the untimed invokeAny method. \ If the run-if-queue-full attribute is configured, tasks can also \ run on the task submitter's thread when you use the execute and submit methods. \