reactor-core icon indicating copy to clipboard operation
reactor-core copied to clipboard

Project Loom and Reactor

Open lynch19 opened this issue 2 years ago • 1 comments

Now that virtual threads and structured concurrency are about to get previewed for the first time on JDK19, I'd like to raise the discussion of Loom & Reactor once more. On the referenced issue, @OlegDokuka answered well that Reactor isn't just about easily writing asynchronous code, but also giving the user a bunch of great streaming operators, much better than any stream API currently offers. But still, Reactor has lots to do with making the software non-blocking. @simonbasle @OlegDokuka I'd like to continue the discussion of the future of Reactor with virtual threads and structured concurrency. In my opinion, early support for Loom features can do lots of good for heavy Reactor users. Some heavy questions that come to my mind are:

  • Will a new Loom-based Scheduler get released? And when?
  • Will Reactor release JDK20+ releases include support for using the Reactor operators without Mono and Flux? Or will users need to continue using the .block() operation even if they won't really block?
  • Will Reactor turns its focus to operator-based features & infrastructure-based features (like better observability, and better integration with other technologies like databases, debugging, etc)?
    • There are currently projects like Spring Cloud Function and Spring Cloud Stream that uses Reactor even though they block (Spring Cloud Stream using Reactor without having a reactive binder at all). Will such use cases of Reactor as a powerful processing operators framework become the main intention of the project?
    • Maybe a better integration with the Java stream API should be considered?
  • Will there be a breaking changes release once Reactor support Loom? And what else do you think needs to get changed?
    • A release that will include changing lots of Reactor's internals to be based on virtual threads?
    • How will the support of Reactor for JDK18- look like, after Loom-based JDKs will get released?

I think that Reactor should be the first to get prepared for this change in Java since it affects the need for some of its killer features. Reactor should have answers for these questions, and for more questions similar to this since they're going to come by the time. Webflux & Reactor are pretty popular by now, and there's no user that wants to see the project losing its popularity. Thus Reactor needs to be the first to take this challenge and support Loom, explain the relationship between the projects (and how to seemingly enable them), as well as redesign and rethinking about parts of the Reactor framework that can improve the usage with Loom-included Java.

In my opinion, shifting the Project's purpose a little and making it a functional Java API dedicated to stream processing, data pipelines, APIs and more is the right direction.

lynch19 avatar Jun 17 '22 23:06 lynch19

yeah this is something that we are still monitoring.

we cannot yet answer many of these questions. plus, a good portion of these seem a bit skewed towards a pretty fundamental pivot of Reactor around Loom. there's definitely no commitment that we can make here, it is a big ask!

When we thought about this year's next big release, we ultimately backed down on the original idea of doing a new generation of Reactor around JDK 17 after having listened to our community, which doesn't seem ready to switch away from Java 8. So we settled on 3.5.0 rather than 4.0.0, still supporting Java 8 as the baseline as a result.

That said, Loom was definitely another turning point in our minds. We'll be reconsidering the question of a Reactor 4 when Loom gets closer to GA. for now, JDK19 will see a feature preview.

This makes directly supporting Loom-based classes in core a challenge in the meantime. Perhaps we'll need another module? The Scheduler idea is likely the most realistic option for early Loom support.

The big question is also how much Reactor can benefit from Loom. Keep in mind that Reactor uses lock-free algorithms and datastructures to implement discrete steps in asynchronous pipelines of data that can perform tremendously within the confines of a single thread. This is not that far removed from the relationship between virtual threads and carrier threads in Loom, and the promises of performance Loom brings. As for Structured Concurrency, there are some parallels to be drawn with how Flux represents a whole pipeline - a structure - and how one can cancel the whole thing in a single operation.

simonbasle avatar Jun 20 '22 13:06 simonbasle

While the team works on official support, would it be safe to assume Schedulers.fromExecutorService(Executors.newVirtualThreadPerTaskExecutor()) as the preferred "escape hatch" instead of Schedulers.boundedElastic() in case of blocking I/O on JDK 21+?

aksh1618 avatar Jun 05 '23 12:06 aksh1618

I wouldn't expect this approach to be "safe".

For instance, if you call a blocking operator, like Mono::block() on a Scheduler created this way, it will throw an IllegalStateException with the message "block()/blockFirst()/blockLast() are blocking, which is not supported in thread {name}"

Another risk would be detecting other types of blocking calls when using Blockhound.

We are working on Loom support. The work is currently on the main-loom branch if you'd like to follow that.

chemicL avatar Jun 07 '23 07:06 chemicL

Any news about it? Loom is 7 days away and I can't wait to use them for real in prod, but I like too much the reactor API to give it up… so I'm following this issue for more than a year now 😇.

davinkevin avatar Sep 13 '23 20:09 davinkevin

Hello,

Does someone have any updates?

fragaLY avatar Sep 26 '23 08:09 fragaLY

interesting research from Jetty team: https://webtide.com/do-looms-claims-stack-up-part-2/

kozel-aliaksei avatar Sep 27 '23 15:09 kozel-aliaksei

https://spring.io/blog/2023/10/31/what-new-is-coming-in-reactor-core-3-6-0#virtual-threads-support

kkocel avatar Oct 31 '23 21:10 kkocel

@OlegDokuka / @simonbasle The blog post mentions (emphasis mine):

we introduce support for the VirtualThread class in the new ThreadPerTaskBoundedElasticScheduler, which is going to be automatically used as implementation for Schedulers.boundedElastic().

... which sounds like the boundedElastic() scheduler will use VirtualThreads by default on Java 21.

But then the post later says:

you will have a VirtualThread instance carrying scheduled work once you run your app on Java 21 and set a -Dreactor.schedulers.defaultBoundedElasticOnVirtualThreads=true system property.

...which sounds like that system property also needs to be set.

So, it's not quite clear if the boundedElastic() scheduler will use VirtualThreads by default on Java 21, or still requires setting that system property. Can you clarify?

If the system property is indeed required, perhaps the first sentence could be updated to say something like:

we introduce support for the VirtualThread class in the new ThreadPerTaskBoundedElasticScheduler, which will be used as the implementation for Schedulers.boundedElastic() if the reactor.schedulers.defaultBoundedElasticOnVirtualThreads system property is set to true.

philsttr avatar Nov 02 '23 14:11 philsttr

@philsttr thanks for bringing that up. I updated the blogpost so it says now

we introduce support for the VirtualThread class in the new ThreadPerTaskBoundedElasticScheduler, which will be used as the implementation for Schedulers.boundedElastic() under certain conditions.

I removed automatic and added under certain conditions to keep the intrigue 😌

OlegDokuka avatar Nov 15 '23 08:11 OlegDokuka

I'm closing this issue since we added minimal support need. Folks, please open a dedicated feature requires once something great comes in your head

OlegDokuka avatar Nov 16 '23 12:11 OlegDokuka