Skip to content

GROOVY-12457: Blocking parallel-collection callbacks can fail to run a queued sibling task - #2986

Open
daniellansun wants to merge 1 commit into
masterfrom
GROOVY-12457
Open

daniellansun wants to merge 1 commit into
masterfrom
GROOVY-12457

Conversation

@daniellansun

@daniellansun daniellansun commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

https://issues.apache.org/jira/browse/GROOVY-12457

See also the flaky test:

ParallelCollectionTest > testEachParallelRunsConcurrently() FAILED
    java.lang.reflect.UndeclaredThrowableException
        at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
        at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
        at java.base/java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:540)
        at java.base/java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:567)
        at java.base/java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:653)
        at org.codehaus.groovy.runtime.ParallelCollectionExtensions.lambda$eachParallel$1(ParallelCollectionExtensions.java:87)
        at org.codehaus.groovy.runtime.ParallelCollectionExtensions.withCurrentFJP(ParallelCollectionExtensions.java:298)
        at org.codehaus.groovy.runtime.ParallelCollectionExtensions.eachParallel(ParallelCollectionExtensions.java:86)
        at TestScript104$_run_closure1.doCall(TestScript104.groovy:13)
        at groovy.lang.Closure.invokeHandle(Closure.java:647)
        at groovy.lang.Closure.invokeCached(Closure.java:618)
        at groovy.lang.Closure.call(Closure.java:584)
        at org.codehaus.groovy.runtime.ConvertedClosure.invokeCustom(ConvertedClosure.java:55)
        at org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:115)
        at jdk.proxy1/jdk.proxy1.$Proxy49.apply(Unknown Source)
        at groovy.concurrent.AsyncScope.lambda$withScope$0(AsyncScope.java:167)
        at org.apache.groovy.runtime.async.ScopedLocal$Carrier.lambda$call$0(ScopedLocal.java:320)
        at org.apache.groovy.runtime.async.ScopedLocal$ThreadLocalImpl.bind(ScopedLocal.java:428)
        at org.apache.groovy.runtime.async.ScopedLocal$Carrier.lambda$execute$1(ScopedLocal.java:338)
        at org.apache.groovy.runtime.async.ScopedLocal$Carrier.execute(ScopedLocal.java:340)
        at org.apache.groovy.runtime.async.ScopedLocal$Carrier.call(ScopedLocal.java:320)
        at org.apache.groovy.runtime.async.ScopedLocal.where(ScopedLocal.java:220)
        at org.apache.groovy.runtime.async.DefaultAsyncScope.withCurrent(DefaultAsyncScope.java:99)
        at groovy.concurrent.AsyncScope.withCurrent(AsyncScope.java:121)
        at groovy.concurrent.AsyncScope.withScope(AsyncScope.java:167)
        at groovy.concurrent.ParallelScope.lambda$withPool$0(ParallelScope.java:73)
        at org.apache.groovy.runtime.async.ScopedLocal$Carrier.lambda$call$0(ScopedLocal.java:320)
        at org.apache.groovy.runtime.async.ScopedLocal$ThreadLocalImpl.bind(ScopedLocal.java:428)
        at org.apache.groovy.runtime.async.ScopedLocal$Carrier.lambda$execute$1(ScopedLocal.java:338)
        at org.apache.groovy.runtime.async.ScopedLocal$Carrier.execute(ScopedLocal.java:340)
        at org.apache.groovy.runtime.async.ScopedLocal$Carrier.call(ScopedLocal.java:320)
        at org.apache.groovy.runtime.async.ScopedLocal.where(ScopedLocal.java:220)
        at org.apache.groovy.runtime.async.DefaultPool.withCurrent(DefaultPool.java:143)
        at groovy.concurrent.Pool.withCurrent(Pool.java:135)
        at groovy.concurrent.ParallelScope.withPool(ParallelScope.java:73)
        at TestScript104.run(TestScript104.groovy:8)
        at groovy.lang.GroovyShell.evaluate(GroovyShell.java:552)
        at groovy.lang.GroovyShell.evaluate(GroovyShell.java:587)
        at groovy.lang.GroovyShell.evaluate(GroovyShell.java:571)
        at groovy.test.GroovyAssert.assertScript(GroovyAssert.java:107)
        at groovy.test.GroovyAssert.assertScript(GroovyAssert.java:97)
        at groovy.concurrent.ParallelCollectionTest.testEachParallelRunsConcurrently(ParallelCollectionTest.groovy:46)

        Caused by:
        java.lang.reflect.UndeclaredThrowableException
            at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
            at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
            at java.base/java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:540)
            at java.base/java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:567)
            at java.base/java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:670)
            at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:160)
            at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(ForEachOps.java:174)
            at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
            at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
            at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:765)
            at org.codehaus.groovy.runtime.ParallelCollectionExtensions.lambda$eachParallel$0(ParallelCollectionExtensions.java:87)
            at java.base/java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1403)
            at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
            at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
            at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
            at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
            at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)

            Caused by:
            java.lang.reflect.UndeclaredThrowableException
                at jdk.proxy1/jdk.proxy1.$Proxy57.accept(Unknown Source)
                at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
                at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:1024)
                at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
                at java.base/java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291)
                at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:754)
                ... 5 more

                Caused by:
                java.util.concurrent.TimeoutException
                    at java.base/java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:259)
                    at java.base/java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:437)
                    at TestScript104$_run_closure1$_closure2.doCall(TestScript104.groovy:15)
                    at groovy.lang.Closure.invokeHandle(Closure.java:647)
                    at groovy.lang.Closure.invokeCached(Closure.java:618)
                    at groovy.lang.Closure.call(Closure.java:584)
                    at org.codehaus.groovy.runtime.ConvertedClosure.invokeCustom(ConvertedClosure.java:55)
                    at org.codehaus.groovy.runtime.ConversionHandler.invoke(ConversionHandler.java:115)
                    ... 11 more

@codecov-commenter

codecov-commenter commented Oct 18, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.22222% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.4222%. Comparing base (d77e6df) to head (ef1eba6).

Files with missing lines Patch % Lines
...s/groovy/runtime/ParallelCollectionExtensions.java 91.9540% 6 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                 @@
##               master      #2986        +/-   ##
==================================================
+ Coverage     72.4166%   72.4222%   +0.0056%     
- Complexity      40606      40633        +27     
==================================================
  Files            1643       1643                
  Lines          142633     142698        +65     
  Branches        26788      26790         +2     
==================================================
+ Hits           103290     103345        +55     
- Misses          29850      29855         +5     
- Partials         9493       9498         +5     
Files with missing lines Coverage Δ
...a/org/apache/groovy/runtime/async/DefaultPool.java 63.0435% <100.0000%> (-0.7863%) ⬇️
...s/groovy/runtime/ParallelCollectionExtensions.java 90.4762% <91.9540%> (+0.4762%) ⬆️

... and 13 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

JMH summary — classic (commit c28bff4)

Speedup vs trailing 90-day baseline on gh-pages. Higher = faster.
1.00 = in line with history. Per-benchmark ratio, geomean within group.
Time-per-op units inverted so direction is consistent. The calibrated
column divides out this runner's speed vs the baseline hardware, as
measured by Groovy-independent pure-Java ruler benchmarks.

Group Speedup Calibrated n
bench 0.943 × 0.964 × 124
core 1.273 × 1.217 × 108
grails 1.139 × 0.958 × 80

⚠️ 1 benchmark at least 1.5× slower than the 90-day baseline:

  • org.apache.groovy.bench.SameClassesGuardMhBench.collector_arity2 — 1.55× slower (calibrated)

⚠️ Runner speed differs ≥15% from the historical baseline hardware for: core-hz, grails-ez. Raw speedups are not meaningful for those parts — use the calibrated column.

Runner calibration (this run vs baseline hardware): bench 0.97× (27 rulers) · core-ag 0.94× (3 rulers) · core-hz 1.27× (3 rulers) · grails-ad 0.96× (3 rulers) · grails-ez 1.42× (3 rulers)

Baseline: dev/bench/jmh/<part>/classic/data.js on gh-pages, trailing 90 days. Daily dashboard · Per-suite raw data

@github-actions

github-actions Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

JMH summary — indy (commit c28bff4)

Speedup vs trailing 90-day baseline on gh-pages. Higher = faster.
1.00 = in line with history. Per-benchmark ratio, geomean within group.
Time-per-op units inverted so direction is consistent. The calibrated
column divides out this runner's speed vs the baseline hardware, as
measured by Groovy-independent pure-Java ruler benchmarks.

Group Speedup Calibrated n
bench 0.980 × 1.037 × 124
core 2.312 × 2.422 × 108
grails 1.692 × 1.457 × 80

⚠️ 1 benchmark at least 1.5× slower than the 90-day baseline:

  • org.apache.groovy.perf.grails.MetaclassVariationBench.perInstanceMetaclass — 1.60× slower (calibrated)

⚠️ Runner speed differs ≥15% from the historical baseline hardware for: grails-ez. Raw speedups are not meaningful for those parts — use the calibrated column.

Runner calibration (this run vs baseline hardware): bench 0.95× (27 rulers) · core-ag 0.96× (3 rulers) · core-hz 0.95× (3 rulers) · grails-ad 0.93× (3 rulers) · grails-ez 1.39× (3 rulers)

Baseline: dev/bench/jmh/<part>/indy/data.js on gh-pages, trailing 90 days. Daily dashboard · Per-suite raw data

@sonarqubecloud

Copy link
Copy Markdown

@testlens-app

testlens-app Bot commented Oct 18, 2026

Copy link
Copy Markdown

✅ All tests passed ✅

🏷️ Commit: ef1eba6
▶️ Tests: 122144 executed
⚪️ Checks: 33/33 completed


Learn more about TestLens at testlens.app/docs.

This branch has not been deployed

No deployments
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.

2 participants