This is an automated email from the ASF dual-hosted git repository.

matrei pushed a commit to branch feat/virtual-thread-promise-factory-seed
in repository https://gitbox.apache.org/repos/asf/grails-core.git


The following commit(s) were added to 
refs/heads/feat/virtual-thread-promise-factory-seed by this push:
     new 3bd188642f fix: virtual-thread executor usage for multi-closure 
promises
3bd188642f is described below

commit 3bd188642fb409db8e657104c4688b5c5959e79b
Author: Mattias Reichel <[email protected]>
AuthorDate: Mon Aug 17 08:18:38 2026 +0200

    fix: virtual-thread executor usage for multi-closure promises
---
 .../future/VirtualThreadPromiseFactory.groovy      |  2 +-
 .../async/VirtualThreadPromiseFactorySpec.groovy   | 22 ++++++++++++++++++++++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git 
a/grails-async/core/src/main/groovy/org/grails/async/factory/future/VirtualThreadPromiseFactory.groovy
 
b/grails-async/core/src/main/groovy/org/grails/async/factory/future/VirtualThreadPromiseFactory.groovy
index fbdccdc7c7..4d6b58786c 100644
--- 
a/grails-async/core/src/main/groovy/org/grails/async/factory/future/VirtualThreadPromiseFactory.groovy
+++ 
b/grails-async/core/src/main/groovy/org/grails/async/factory/future/VirtualThreadPromiseFactory.groovy
@@ -66,7 +66,7 @@ class VirtualThreadPromiseFactory extends 
AbstractPromiseFactory implements Clos
 
         PromiseList<T> list = new PromiseList<>()
         for (Closure<T> closure : closures) {
-            list.add(closure)
+            list.add(createPromise(closure))
         }
         return list as Promise<T>
     }
diff --git 
a/grails-async/core/src/test/groovy/grails/async/VirtualThreadPromiseFactorySpec.groovy
 
b/grails-async/core/src/test/groovy/grails/async/VirtualThreadPromiseFactorySpec.groovy
index 61d8f03f26..7d033719be 100644
--- 
a/grails-async/core/src/test/groovy/grails/async/VirtualThreadPromiseFactorySpec.groovy
+++ 
b/grails-async/core/src/test/groovy/grails/async/VirtualThreadPromiseFactorySpec.groovy
@@ -21,6 +21,7 @@ package grails.async
 import java.util.concurrent.ExecutionException
 
 import org.grails.async.factory.PromiseFactoryBuilder
+import org.grails.async.factory.SynchronousPromiseFactory
 import org.grails.async.factory.future.VirtualThreadPromiseFactory
 import spock.lang.Specification
 
@@ -72,6 +73,27 @@ class VirtualThreadPromiseFactorySpec extends Specification {
         factory.close()
     }
 
+    void 'multi-closure promises use the virtual thread executor'() {
+        given:
+        def factory = new VirtualThreadPromiseFactory()
+        // PromiseList normally delegates closure creation to the global 
factory. Using a
+        // synchronous factory makes the unfixed implementation run on this 
test thread,
+        // while the corrected implementation must still use this factory's 
virtual threads.
+        Promises.promiseFactory = new SynchronousPromiseFactory()
+
+        when:
+        List<Boolean> result = (factory.createPromise(
+            { Thread.currentThread().isVirtual() },
+            { Thread.currentThread().isVirtual() }
+        ) as Promise<List<Boolean>>).get()
+
+        then:
+        result == [true, true]
+
+        cleanup:
+        factory.close()
+    }
+
     void 'onComplete resolves to the waited values and invokes the callback 
for its side effect'() {
         given:
         def factory = new VirtualThreadPromiseFactory()

Reply via email to