Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/akarnokd/rxjavafiberinterop
Library for interoperation between RxJava 3 and JDK 21+ Virtual Threads
https://github.com/akarnokd/rxjavafiberinterop
continuation fiber interoperation reactive rxjava virtual-thread virtual-threads
Last synced: 17 days ago
JSON representation
Library for interoperation between RxJava 3 and JDK 21+ Virtual Threads
- Host: GitHub
- URL: https://github.com/akarnokd/rxjavafiberinterop
- Owner: akarnokd
- License: apache-2.0
- Created: 2019-07-31T13:39:38.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2023-12-27T04:17:57.000Z (11 months ago)
- Last Synced: 2024-10-14T12:26:47.285Z (about 1 month ago)
- Topics: continuation, fiber, interoperation, reactive, rxjava, virtual-thread, virtual-threads
- Language: Java
- Homepage:
- Size: 441 KB
- Stars: 36
- Watchers: 4
- Forks: 4
- Open Issues: 6
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# RxJavaFiberInterop
Library for interoperation between RxJava 3 and JDK 21's Virtual Threads (aka Fibers, Project Loom).
[![codecov.io](http://codecov.io/github/akarnokd/RxJavaFiberInterop/coverage.svg?branch=master)](http://codecov.io/github/akarnokd/RxJavaFiberInterop?branch=master)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.akarnokd/rxjava3-fiber-interop/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.akarnokd/rxjava3-fiber-interop)```groovy
dependencies {
implementation "com.github.akarnokd:rxjava3-fiber-interop:0.0.18"
}
```Requires a JDK that has Virtual Threads as standard feature (i.e., not preview), such as [https://jdk.java.net/21/](https://jdk.java.net/21/).
# Components
## FiberInterop
### Schedulers
Currently, the Virtual Thread API does not offer public means to specify the carrier thread(pool) thus it is not possible to use RxJava `Scheduler`s as such.
You can use the `Schedulers.from` though to convert the Fork-Join-pool backed standard Virtual Thread Executor into an RxJava `Scheduler`:
```java
var vte = Executors.newVirtualThreadExecutor();
Scheduler vtScheduler = Schedulers.from(vte);// sometime later
vte.close();
```You can then use `vtScheduler` from the example with `subscribeOn` and `observeOn` to let traditional functional callbacks to block virtually:
```java
Observable.fromCallable(() -> someBlockingNetworkCall())
.subscribeOn(vtScheduler)
.observeOn(vtScheduler)
.map(v -> someOtherBlockingCall(v))
.observeOn(uiThread)
.subscribe(v -> label.setText(v), e -> label.setText(e.toString()));
```:information_source: You need the special operators below to make RxJava's non-blocking backpressure into virtually blocked backpressure.
### create
Creates a `Flowable` from a generator callback, that can emit via `FiberEmitter`, run on an `ExecutorService` provided by the user and
is suspended automatically upon backpressure. The callback is executed inside the virtual thread thus you can call the usual blocking APIs and get suspensions the same way.The created `Flowable` will complete once the callback returns normally or with an error if the callback throws an exception.
```java
try (var scope = Executors.newVirtualThreadExecutor()) {
FiberInterop.create(emitter -> {
for (int i = 1; i <= 5; i++) {
emitter.emit(1);
}
}, scope)
.test()
.awaitDone(5, TimeUnit.SECONDS)
.assertResult(1, 2, 3, 4, 5);
}
```### transform
Transforms each upstream value via a callback that can emit zero or more values for each of those upstream values, run on an `ExecutorService` provided by the user and is suspended automatically upon backpressure. The callback is executed inside the virtual thread thus you can call the usual blocking APIs and get suspensions the same way.
```java
try (var scope = Executors.newVirtualThreadExecutor()) {
Flowable.range(1, 5)
.compose(FiberInterop.transform((value, emitter) -> {
emitter.emit(value);
emitter.emit(value + 1);
}, scope))
.test()
.awaitDone(5, TimeUnit.SECONDS)
.assertResult(1, 2, 2, 3, 3, 4, 4, 5, 5, 6);
}
```### blockingXXX
RxJava uses `java.util.concurrent` locks and `CountDownLatches` via its `blockingXXX` which will automatically work within a virtual thread. Therefore, there is no need for a separate interop operator. Just block.
```java
try (var scope = Executors.newVirtualThreadExecutor()) {
scope.submit(() -> {
var v = Flowable.just(1)
.delay(1, TimeUnit.SECONDS)
.blockingLast();
System.out.println(v);
});
}
```