reactor / reactor-core

Non-Blocking Reactive Foundation for the JVM
http://projectreactor.io
Apache License 2.0
4.88k stars 1.18k forks source link

Provide more ways to mark a thread as non-blocking #3833

Open trustin opened 4 days ago

trustin commented 4 days ago

Motivation

We maintain a reactive web framework called Armeria (https://armeria.dev). It allows a user to implement a reactive web application using the Reactive Streams implementation of their choice. A user can choose from Armeria's own Reactive Streams implementation, Reactor and RxJava. Therefore, we don't have any mandatory dependency on Reactor and RxJava to keep our dependencies lean and stay unopinionated, and we want to keep it this way.

When a user writes their application using Armeria and Reactor, Armeria needs to tell Reactor that its event loop threads are non-blocking. Reactor currently determines whether a thread is non-blocking or not using Schedulers.isInNonBlockingThread() and Schedulers.isNonBlockingThread() (here).

It means, for Armeria to mark a thread as non-blocking, Armeria needs to make its event loop thread class implement the NonBlocking interface, e.g.:

public class ArmeriaEventLoopThread extends Thread implements NonBlocking { ... }

However, because Armeria has no mandatory dependency on Reactor, JVM will fail to load ArmeriaEventLoopThread when Reactor is not available in the classpath, if we introduce NonBlocking into our class hierarchy.

Desired solution

Provide an alternative way to mark a thread (or thread class) as non-blocking, so that Armeria team can define a non-blocking thread without introducing mandatory runtime dependency on reactor-core. There are a few options to solve this:

Considered alternatives

trustin commented 4 days ago

Other frameworks like Netty will benefit from resolving this issue as well, since Netty could mark their event loop thread classes as non-blocking out of the box. (but I'm not sure whether they want to introduce an additional dependency or rename their classes, so they might prefer Java SPI approach.) /cc @normanmaurer @chrisvest

chrisvest commented 4 days ago

A possible neutral annotation could be https://github.com/JetBrains/java-annotations/blob/master/java-annotations/src/main/java/org/jetbrains/annotations/NonBlockingExecutor.java And the check could be that the thread, or any implemented interface, has this annotation. Would be easy to retrofit the NonBlocking interface this way.

trustin commented 4 days ago

Thanks for the input, @chrisvest. That's also a feasible option. Let me stay tuned to what Reactor maintainers think. Once agreed, I'd be happy to send out a PR.