micronaut-projects / micronaut-projects/micronaut-rxjava3
Micronaut v3.8.8 and RxJava3 handling of reactive streams and ExecuteOn differs from v3.3.4 with RxJava2
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 5
- Forks
- 4
- Avg merge
- 3h 36m
- Merged PRs (30d)
- 8
Description
### Expected Behavior
## Summary
Full Description here - https://github.com/rdamus/mn3_8_8_rxjava3/blob/main/README.md
### Overview
Recently upgraded from micronaut 3.3.4 to 3.8.7, also updated all `rxjava2` to `rxjava3` and now can no longer use the
Micronaut Declarative Client with `Flowable.blocking*` calls against a reactive controller.
The same functionality worked for months in production; now it is not possible to stream from the endpoint. Previously
the `http.client.read-timeout` and `read-idle-timeout` variables were set to their default values
Here [is](https://github.com/rdamus/mn3_8_8_rxjava3) a demo project i built to show change in behavior of the reactive streams when upgrading to `micronaut-3.8.8` and `rxjava3`. The project shows that i can no longer use the `Flowable.blockingNext()` or `Flowable.blockingIterable()` to stream results from a reactive endpoint that uses a `Flowable` and `@ExcecuteOn` annotation to offload the work
### Expected Behavior
The client would return a stream of `IngestReport` objects and the app using the client could step through the stream
### Previous Behavior
In `micronaut-3.3.4` (plugin version `3.3.2`) and `rxjava2` it was possible to do the following:
Declare a `Flowable` method in a parent inerface, and then extend this interface in a declarative client
```groovy
interface LoanOperations {
@Get(uri = '/ingest/tracker/{loanTapeId}/schema/{schemaId}', processes = MediaType.APPLICATION_JSON_STREAM)
Flowable ingestTracker(@NonNull Long loanTapeId, @NonNull Long schemaId)
}
@Client(id='loan', path='${loan.context-path:/}${loan.api.version}/loan')
interface LoanClient extends LoanOperations{}
```
Implement the method and execute the call on the TaskExecutors.IO thread because pre-processing causes this `Flowable`
to not start emitting immediately
```groovy
@Controller('/${loan.api.version}/loan')
class LoanController{
@ExecuteOn(TaskExecutors.IO)
Flowable ingestTracker(@NonNull Long loanTapeId, @NonNull Long schemaId) {
//pre-processing that takes up to a minute
//start emitting the IngestReport objects
}
}
```
i used to be able to call the `Flowable.blockingIterable()` from an app and get an iterator and the code would happily wait
(without setting the `http.client.read-timeout` or changing the `read-idle-timeout`) and the following would just work:
```groovy
//either of these would work
//def iterator = loanClient.ingestTracker(persistedTape.id, persistedSchema.id).blockingNext().iterator()
def iterator = loanClient.ingestTracker(persistedTape.id, persistedSchema.id).blockingIterable().iterator()
def report = null
while( iterator.hasNext() ){
report = iterator.next()
if( report.state.is IngestReport.State.COMPLETE ){
log.info "COMPLETE!"
}
}
```
### Actual Behaviour
A `ReadTimeoutException` is thrown while the client waits for the Flowable to begin because the endpoint does some
pre-processing that takes up to 60 seconds. Thus the `ReadTimeoutException` is thrown after 10 seconds.
### Steps To Reproduce
Download [the project](https://github.com/rdamus/mn3_8_8_rxjava3/tree/main) i put together and run the tests. All the tests in the `LoanClientSpec` will pass, meaning the `ReadTimeoutException` is being thrown, which is different from the previously observed behavior in micronaut `3.3.4` with `rxjava2`
### Environment Information
- Operating System: Ubuntu 22.04
- JDK: azul-15 (15.0.3) or openjdk "11.0.11" 2021-04-20 LTS
### Example Application
https://github.com/rdamus/mn3_8_8_rxjava3
### Version
3.8.8
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by downloading the linked mn3_8_8_rxjava3 example and running the LoanClientSpec tests to reproduce the ReadTimeoutException. Compare the Micronaut 3.8.8/RxJava3 behavior with the documented 3.3.4/RxJava2 behavior around Flowable, @ExecuteOn, and the client timeouts. Done means the client can wait through the controller's preprocessing and consume the emitted IngestReport stream without an unexpected read timeout.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100