Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Investigate coroutines #1957

Open
FroMage opened this issue Apr 9, 2019 · 18 comments
Open

Investigate coroutines #1957

FroMage opened this issue Apr 9, 2019 · 18 comments
Assignees

Comments

@FroMage
Copy link
Member

FroMage commented Apr 9, 2019

  • Look into making Quasar work on SVM
  • Explore EA-Async
@FroMage
Copy link
Member Author

FroMage commented Apr 9, 2019

OK, so it was not easy, and this is all still very experimental, but:

  • I've added Quasar instrumentation (to Hibernate Panache ORM for now)
  • I've fixed CL-related bugs in our test CL and QuarkusClassWriter (we need to figure out why these were only causing invalid class files in this test and not in other applications, it seems quite weird and scary)
  • I've added a test in PanacheFunctionalityTest.testAsync() that works on the JVM and fails on SVM during build with:
[INFO] [io.quarkus.creator.phase.nativeimage.NativeImagePhase] Running Quarkus native-image plugin on Java HotSpot(TM) 64-Bit Server VM
[INFO] [io.quarkus.creator.phase.nativeimage.NativeImagePhase] /home/stephane/no-backup/src/graalvm-ce-1.0.0-rc14/bin/native-image -J-Djava.util.logging.manager=org.jboss.logmanager.LogManager -H:InitialCollectionPolicy=com.oracle.svm.core.genscavenge.CollectionPolicy$BySpaceAndTime -jar quarkus-integration-test-hibernate-orm-panache-999-SNAPSHOT-runner.jar -J-Djava.util.concurrent.ForkJoinPool.common.parallelism=1 -H:+PrintAnalysisCallTree -H:-AddAllCharsets -H:EnableURLProtocols=http,https --enable-all-security-services -H:NativeLinkerOption=-no-pie -H:-SpawnIsolates -H:+JNI --no-server -H:-UseServiceLoaderFeature -H:+StackTrace
[quarkus-integration-test-hibernate-orm-panache-999-SNAPSHOT-runner:31060]    classlist:  18,729.38 ms
[quarkus-integration-test-hibernate-orm-panache-999-SNAPSHOT-runner:31060]        (cap):   1,246.61 ms
[quarkus-integration-test-hibernate-orm-panache-999-SNAPSHOT-runner:31060]        setup:   2,585.64 ms
17:40:29,375 INFO  [org.hib.Version] HHH000412: Hibernate Core {5.4.2.Final}
17:40:29,403 INFO  [org.hib.ann.com.Version] HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
17:40:29,438 INFO  [org.hib.dia.Dialect] HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
17:40:31,309 INFO  [com.arj.ats.arjuna] ARJUNA012170: TransactionStatusManager started on port 45635 and host 127.0.0.1 with service com.arjuna.ats.arjuna.recovery.ActionStatusService
17:40:32,017 INFO  [org.xnio] XNIO version 3.7.0.Final
17:40:32,135 INFO  [org.xni.nio] XNIO NIO Implementation Version 3.7.0.Final
17:40:34,124 INFO  [org.jbo.threads] JBoss Threads version 3.0.0.Alpha4
QUASAR WARNING: Quasar Java Agent isn't running. If you're using another instrumentation method you can ignore this message; otherwise, please refer to the Getting Started section in the Quasar documentation.
[quarkus-integration-test-hibernate-orm-panache-999-SNAPSHOT-runner:31060]     analysis:  23,730.77 ms
Printing call tree to /home/stephane/src/java-eclipse/quarkus/integration-tests/hibernate-orm-panache/target/reports/call_tree_quarkus-integration-test-hibernate-orm-panache-999-SNAPSHOT-runner_20190409_174100.txt
Printing list of used classes to /home/stephane/src/java-eclipse/quarkus/integration-tests/hibernate-orm-panache/target/reports/used_classes_quarkus-integration-test-hibernate-orm-panache-999-SNAPSHOT-runner_20190409_174102.txt
Printing list of used packages to /home/stephane/src/java-eclipse/quarkus/integration-tests/hibernate-orm-panache/target/reports/used_packages_quarkus-integration-test-hibernate-orm-panache-999-SNAPSHOT-runner_20190409_174102.txt
Error: unsupported features in 2 methods
Detailed message:
Error: Exception handler can be reached by both normal and exceptional control flow
Call path from entry point to com.github.fromage.quasi.strands.dataflow.Val$1.run(): 
	at com.github.fromage.quasi.strands.dataflow.Val$1.run(Val.java)
	at com.github.fromage.quasi.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:45)
	at com.github.fromage.quasi.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:33)
	at com.github.fromage.quasi.fibers.Fiber.run(Fiber.java:1100)
	at com.github.fromage.quasi.fibers.Fiber.run1(Fiber.java:1095)
	at com.github.fromage.quasi.fibers.Fiber.exec(Fiber.java:791)
	at com.github.fromage.quasi.fibers.FiberForkJoinScheduler$FiberForkJoinTask.exec1(FiberForkJoinScheduler.java:272)
	at com.github.fromage.quasi.concurrent.forkjoin.ParkableForkJoinTask.doExec(ParkableForkJoinTask.java:118)
	at com.github.fromage.quasi.concurrent.forkjoin.ParkableForkJoinTask.exec(ParkableForkJoinTask.java:75)
	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
	at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:473)
	at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:193)
	at com.oracle.svm.core.code.IsolateEnterStub.PosixJavaThreads_pthreadStartRoutine_e1f4a8c0039f8337338252cd8734f63a79b5e3df(generated:0)
--------------------------------------------------------------------------------------------
-- WARNING: The above stack trace is not a real stack trace, it is a theoretical call tree---
-- If an interface has multiple implementations SVM will just display one potential call  ---
-- path to the interface. This is often meaningless, and what you actually need to know is---
-- the path to the constructor of the object that implements this interface.              ---
-- Quarkus has attempted to generate a more meaningful call flow analysis below          ---
---------------------------------------------------------------------------------------------

Possible path to com.github.fromage.quasi.strands.dataflow.Val$1.run():v
	com.github.fromage.quasi.strands.dataflow.Val$1.run():v
This is an implementation of com.github.fromage.quasi.strands.SuspendableRunnable printing path to constructors of com.github.fromage.quasi.strands.dataflow.Val$1


Possible path to com.github.fromage.quasi.strands.dataflow.Val$1.<init>(com.github.fromage.quasi.strands.dataflow.Val, com.github.fromage.quasi.strands.SuspendableCallable):v
	com.github.fromage.quasi.strands.dataflow.Val$1.<init>(com.github.fromage.quasi.strands.dataflow.Val, com.github.fromage.quasi.strands.SuspendableCallable):v
	com.github.fromage.quasi.strands.dataflow.Val.<init>(com.github.fromage.quasi.fibers.FiberScheduler, com.github.fromage.quasi.strands.SuspendableCallable):v
	com.github.fromage.quasi.strands.dataflow.Val.<init>(com.github.fromage.quasi.strands.SuspendableCallable):v
	com.github.fromage.quasi.strands.dataflow.Val.<init>():v
	com.github.fromage.quasi.fibers.Fiber.<init>(java.lang.String, com.github.fromage.quasi.fibers.FiberScheduler, int, com.github.fromage.quasi.strands.SuspendableCallable):v
	com.github.fromage.quasi.fibers.Fiber.<init>(java.lang.String, int, com.github.fromage.quasi.strands.SuspendableCallable):v
	com.github.fromage.quasi.fibers.Fiber.<init>(java.lang.String, int, com.github.fromage.quasi.strands.SuspendableRunnable):v
	com.github.fromage.quasi.fibers.Fiber.<init>(com.github.fromage.quasi.strands.SuspendableRunnable):v
	io.quarkus.example.panache.TestEndpoint.fiber(com.github.fromage.quasi.strands.SuspendableCallable):j
	io.quarkus.example.panache.TestEndpoint.getAsync():j
	io.quarkus.example.panache.TestEndpoint.getAsync():j
	com.oracle.svm.reflect.TestEndpoint_getAsync_87e7cd4eaafc86e2d3f3ee6267ed235c8b29fb4a.invoke(java.lang.Object, java.lang.Object[]):j
This is an implementation of sun.reflect.MethodAccessor printing path to constructors of com.oracle.svm.reflect.TestEndpoint_getAsync_87e7cd4eaafc86e2d3f3ee6267ed235c8b29fb4a



Original exception that caused the problem: org.graalvm.compiler.core.common.PermanentBailoutException: Exception handler can be reached by both normal and exceptional control flow
	at org.graalvm.compiler.java.BciBlockMapping.addSuccessor(BciBlockMapping.java:763)
	at org.graalvm.compiler.java.BciBlockMapping.iterateOverBytecodes(BciBlockMapping.java:614)
	at org.graalvm.compiler.java.BciBlockMapping.build(BciBlockMapping.java:517)
	at org.graalvm.compiler.java.BciBlockMapping.create(BciBlockMapping.java:1109)
	at org.graalvm.compiler.java.BytecodeParser.build(BytecodeParser.java:807)
	at org.graalvm.compiler.java.BytecodeParser.buildRootMethod(BytecodeParser.java:785)
	at org.graalvm.compiler.java.GraphBuilderPhase$Instance.run(GraphBuilderPhase.java:95)
	at org.graalvm.compiler.phases.Phase.run(Phase.java:49)
	at org.graalvm.compiler.phases.BasePhase.apply(BasePhase.java:197)
	at org.graalvm.compiler.phases.Phase.apply(Phase.java:42)
	at org.graalvm.compiler.phases.Phase.apply(Phase.java:38)
	at com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.parse(MethodTypeFlowBuilder.java:213)
	at com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.apply(MethodTypeFlowBuilder.java:332)
	at com.oracle.graal.pointsto.flow.MethodTypeFlow.doParse(MethodTypeFlow.java:310)
	at com.oracle.graal.pointsto.flow.MethodTypeFlow.ensureParsed(MethodTypeFlow.java:300)
	at com.oracle.graal.pointsto.flow.MethodTypeFlow.addContext(MethodTypeFlow.java:107)
	at com.oracle.graal.pointsto.DefaultAnalysisPolicy$DefaultVirtualInvokeTypeFlow.onObservedUpdate(DefaultAnalysisPolicy.java:191)
	at com.oracle.graal.pointsto.flow.TypeFlow.notifyObservers(TypeFlow.java:352)
	at com.oracle.graal.pointsto.flow.TypeFlow.update(TypeFlow.java:394)
	at com.oracle.graal.pointsto.BigBang$2.run(BigBang.java:508)
	at com.oracle.graal.pointsto.util.CompletionExecutor.lambda$execute$0(CompletionExecutor.java:169)
	at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402)
	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Error: Exception handler can be reached by both normal and exceptional control flow
Call path from entry point to io.quarkus.example.panache.TestEndpoint.lambda$fiber$48e7e753$1(SuspendableCallable, CompletableFuture): 
	at io.quarkus.example.panache.TestEndpoint.lambda$fiber$48e7e753$1(TestEndpoint.java)
	at io.quarkus.example.panache.TestEndpoint$$Lambda$579/1565660052.run(Unknown Source)
	at com.github.fromage.quasi.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:45)
	at com.github.fromage.quasi.strands.SuspendableUtils$VoidSuspendableCallable.run(SuspendableUtils.java:33)
	at com.github.fromage.quasi.fibers.Fiber.run(Fiber.java:1100)
	at com.github.fromage.quasi.fibers.Fiber.run1(Fiber.java:1095)
	at com.github.fromage.quasi.fibers.Fiber.exec(Fiber.java:791)
	at com.github.fromage.quasi.fibers.FiberForkJoinScheduler$FiberForkJoinTask.exec1(FiberForkJoinScheduler.java:272)
	at com.github.fromage.quasi.concurrent.forkjoin.ParkableForkJoinTask.doExec(ParkableForkJoinTask.java:118)
	at com.github.fromage.quasi.concurrent.forkjoin.ParkableForkJoinTask.exec(ParkableForkJoinTask.java:75)
	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
	at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:473)
	at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:193)
	at com.oracle.svm.core.code.IsolateEnterStub.PosixJavaThreads_pthreadStartRoutine_e1f4a8c0039f8337338252cd8734f63a79b5e3df(generated:0)
--------------------------------------------------------------------------------------------
-- WARNING: The above stack trace is not a real stack trace, it is a theoretical call tree---
-- If an interface has multiple implementations SVM will just display one potential call  ---
-- path to the interface. This is often meaningless, and what you actually need to know is---
-- the path to the constructor of the object that implements this interface.              ---
-- Quarkus has attempted to generate a more meaningful call flow analysis below          ---
---------------------------------------------------------------------------------------------

Possible path to io.quarkus.example.panache.TestEndpoint.lambda$fiber$48e7e753$1(com.github.fromage.quasi.strands.SuspendableCallable, java.util.concurrent.CompletableFuture):v
	io.quarkus.example.panache.TestEndpoint.lambda$fiber$48e7e753$1(com.github.fromage.quasi.strands.SuspendableCallable, java.util.concurrent.CompletableFuture):v
	io.quarkus.example.panache.TestEndpoint$$Lambda$1402d16eacdf9d5d14ca78e42cd2448f1dfc9ea0.run():v
This is an implementation of com.github.fromage.quasi.strands.SuspendableRunnable printing path to constructors of io.quarkus.example.panache.TestEndpoint$$Lambda$1402d16eacdf9d5d14ca78e42cd2448f1dfc9ea0


Possible path to io.quarkus.example.panache.TestEndpoint$$Lambda$1402d16eacdf9d5d14ca78e42cd2448f1dfc9ea0.<init>(com.github.fromage.quasi.strands.SuspendableCallable, java.util.concurrent.CompletableFuture):v
	io.quarkus.example.panache.TestEndpoint$$Lambda$1402d16eacdf9d5d14ca78e42cd2448f1dfc9ea0.<init>(com.github.fromage.quasi.strands.SuspendableCallable, java.util.concurrent.CompletableFuture):v
	io.quarkus.example.panache.TestEndpoint$$Lambda$1402d16eacdf9d5d14ca78e42cd2448f1dfc9ea0.get$Lambda(com.github.fromage.quasi.strands.SuspendableCallable, java.util.concurrent.CompletableFuture):c
	io.quarkus.example.panache.TestEndpoint.fiber(com.github.fromage.quasi.strands.SuspendableCallable):j
	io.quarkus.example.panache.TestEndpoint.getAsync():j
	io.quarkus.example.panache.TestEndpoint.getAsync():j
	com.oracle.svm.reflect.TestEndpoint_getAsync_87e7cd4eaafc86e2d3f3ee6267ed235c8b29fb4a.invoke(java.lang.Object, java.lang.Object[]):j
This is an implementation of sun.reflect.MethodAccessor printing path to constructors of com.oracle.svm.reflect.TestEndpoint_getAsync_87e7cd4eaafc86e2d3f3ee6267ed235c8b29fb4a



Original exception that caused the problem: org.graalvm.compiler.core.common.PermanentBailoutException: Exception handler can be reached by both normal and exceptional control flow
	at org.graalvm.compiler.java.BciBlockMapping.addSuccessor(BciBlockMapping.java:763)
	at org.graalvm.compiler.java.BciBlockMapping.iterateOverBytecodes(BciBlockMapping.java:614)
	at org.graalvm.compiler.java.BciBlockMapping.build(BciBlockMapping.java:517)
	at org.graalvm.compiler.java.BciBlockMapping.create(BciBlockMapping.java:1109)
	at org.graalvm.compiler.java.BytecodeParser.build(BytecodeParser.java:807)
	at org.graalvm.compiler.java.BytecodeParser.buildRootMethod(BytecodeParser.java:785)
	at org.graalvm.compiler.java.GraphBuilderPhase$Instance.run(GraphBuilderPhase.java:95)
	at org.graalvm.compiler.phases.Phase.run(Phase.java:49)
	at org.graalvm.compiler.phases.BasePhase.apply(BasePhase.java:197)
	at org.graalvm.compiler.phases.Phase.apply(Phase.java:42)
	at org.graalvm.compiler.phases.Phase.apply(Phase.java:38)
	at com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.parse(MethodTypeFlowBuilder.java:213)
	at com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.apply(MethodTypeFlowBuilder.java:332)
	at com.oracle.graal.pointsto.flow.MethodTypeFlow.doParse(MethodTypeFlow.java:310)
	at com.oracle.graal.pointsto.flow.MethodTypeFlow.ensureParsed(MethodTypeFlow.java:300)
	at com.oracle.graal.pointsto.flow.MethodTypeFlow.addContext(MethodTypeFlow.java:107)
	at com.oracle.graal.pointsto.flow.StaticInvokeTypeFlow.update(InvokeTypeFlow.java:346)
	at com.oracle.graal.pointsto.BigBang$2.run(BigBang.java:508)
	at com.oracle.graal.pointsto.util.CompletionExecutor.lambda$execute$0(CompletionExecutor.java:169)
	at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402)
	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

Error: Use -H:+ReportExceptionStackTraces to print stacktrace of underlying exception

Which is the cause of the issue I was talking about earlier, with generated exception tables such as:

      Exception table:
         from    to  target type
            45   137   162   Class com/github/fromage/quasi/fibers/SuspendExecution
            45   137   162   Class com/github/fromage/quasi/fibers/RuntimeSuspendExecution
            45   137   137   Class java/lang/reflect/UndeclaredThrowableException
            48    53   120   Class java/lang/Throwable // THIS ONE
           105   117   120   Class java/lang/Throwable // AND THIS ONE
            45   137   153   any

Where both try blocks point to the same catch block. We will need to tweak Quasar to duplicate the try blocks.

@FroMage
Copy link
Member Author

FroMage commented Apr 9, 2019

@FroMage
Copy link
Member Author

FroMage commented Apr 9, 2019

BTW, the biggest differences IMO between Quarkus are:

  • We already forked Quasar (but perhaps master has since caught up with JDK8-11, I need to try it)
  • Quasar will be closer to Loom
  • Quasar is way more complex
  • EA-Async does not support transitive suspendable methods (methods that don't call await but call methods that do), but perhaps it's not an issue. It could even be a good thing, since it limits where people can suspend.
  • Quasar supports iterating streams by calling await in a SuspendableIterator (with my patch). EA-Async cannot because it requires transitive suspension. Again, perhaps it's a good thing.

@dmlloyd
Copy link
Member

dmlloyd commented Apr 9, 2019

It's really interesting/strange that SVM complains about this; I wonder if they make some special assumptions. But yeah theoretically it should be possible to duplicate the exception handler blob.

@FroMage
Copy link
Member Author

FroMage commented Apr 9, 2019

Ah yes, right, it's the handler we need to duplicate, not the try block, of course :)

@FroMage
Copy link
Member Author

FroMage commented Apr 10, 2019

So I tried EA-Async in https://github.com/FroMage/quarkus/tree/ea-async and it Just Works™.

With the caveats that I mentioned earlier, but still.

@FroMage
Copy link
Member Author

FroMage commented Apr 10, 2019

Ferget the other branch: use https://github.com/FroMage/quarkus/tree/coroutines to get quarkus-coroutines-ea-async and quarkus-coroutines-quasar modules.

@FroMage
Copy link
Member Author

FroMage commented Apr 11, 2019

Well, I tried ea-coroutines in panache-rx and that turned out pretty amazing: FroMage@cbe1aca?diff=split

@FroMage
Copy link
Member Author

FroMage commented Apr 11, 2019

Ah no, sometimes ea-async does not work in SVM:

Error: Non-reducible loop
Call path from entry point to io.quarkus.example.panache.TestEndpoint.async$testRxModel(TestEndpoint, CompletionStage, List, RxPerson, long, RxPerson, RxPerson, int, int, Object): 
	at io.quarkus.example.panache.TestEndpoint.async$testRxModel(TestEndpoint.java)
	at io.quarkus.example.panache.TestEndpoint$$Lambda$589/1206642173.apply(Unknown Source)
	at java.util.concurrent.CompletableFuture.uniCompose(CompletableFuture.java:952)
	at java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:926)
	at java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:442)
	at org.xnio.nio.WorkerThread.safeRun(WorkerThread.java:612)
	at org.xnio.nio.WorkerThread.run(WorkerThread.java:479)
	at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:473)
	at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:193)
	at com.oracle.svm.core.code.IsolateEnterStub.PosixJavaThreads_pthreadStartRoutine_e1f4a8c0039f8337338252cd8734f63a79b5e3df(generated:0)

@FroMage
Copy link
Member Author

FroMage commented Apr 11, 2019

DAMNIT.

@FroMage
Copy link
Member Author

FroMage commented Apr 12, 2019

Appears to be similar to oracle/graal#366 because I can get around it by inlining my loop (as a workaround).

@gsmet gsmet added the pinned Issue will never be marked as stale label Nov 13, 2019
@cromefire
Copy link

Coroutines should work well now with 20.1
Also #10162 seems to be a (active) duplicate of this

@ambition-consulting
Copy link

@FroMage Any plans on retesting with GraalVM 2.1?

@FroMage
Copy link
Member Author

FroMage commented Oct 19, 2020

Not ATM, no, I've no time. But if you want to try, let us know :)

@FroMage
Copy link
Member Author

FroMage commented Mar 26, 2021

I tested with 20.3.1 and I still get the same issue. It looks like they didn't fix it in general. Perhaps they special-cased Kotlin patterns, or Kotlin changed their implementation?

Error: Exception handler can be reached by both normal and exceptional control flow
Call path from entry point to com.example.Fibers.lambda$fiber$d718b233$1(SuspendableCallable, CompletableFuture): 
	at com.example.Fibers.lambda$fiber$d718b233$1(Fibers.java)
	at com.example.Fibers$$Lambda$644/0x00000007c0ec1440.run(Unknown Source)

@dmlloyd
Copy link
Member

dmlloyd commented Apr 1, 2021

It's interesting that they care whether an exception handler is reachable via normal control flow. Especially since the distinction between an exception handler and normal control flow is so fine: for example, what if my exception handler were simply a GOTO to normal program execution? Surely that must be allowed, since empty catch blocks seem to function just fine.

I wonder whether it would be worth figuring out a change to the Quasar code to vector the exception code through a GOTO, so that there is never a GOTO (or fall-through) with the same destination as an exception handler. Maybe in conjunction with allocating a local variable for the exception so that the code doesn't get somehow folded by GraalVM back into the construct that was invalid in the first place.

@FroMage
Copy link
Member Author

FroMage commented Apr 2, 2021

At the time, we thought about it, or perhaps a variation such as duplicating the exception blocks. But yeah, moving it out and using a GOTO could work, but also means having to pass access to local variables, some of which are not mutable and may require mutation.

At the time, we though that was too much trouble to fix. I still feel like, at least for me, it'd be a rabbit hole full of traps.

@AlexMog
Copy link

AlexMog commented Oct 19, 2021

Hello,
Don't know if this subject is still in progress or if tascalate async/await was mentioned here, but it should be usable to add async/await pattern to Quarkus I assume: https://github.com/vsilaev/tascalate-async-await
(and, unlike EA Async, it is still maintained)

@cescoffier cescoffier removed the pinned Issue will never be marked as stale label Nov 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants