-
Notifications
You must be signed in to change notification settings - Fork 562
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
Reactive Streams impl #1282
Reactive Streams impl #1282
Conversation
6f031ba
to
f2eaa48
Compare
common/reactive/src/main/java/io/helidon/common/reactive/MultiFlatMapProcessor.java
Outdated
Show resolved
Hide resolved
29a8cb1
to
9ba3ee7
Compare
Rebased on @tomas-langer 's native image changes in the master, sorry for force-push |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this declared R
if onNext
expects it to be X
? (I know, this change is just adapting old to new, but still)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Atomic properties of these are not used. It's better to declare them volatile
. (But I am not even convinced they have to be volatile - the onSubscribe/onNext/onComplete/onError protocol is single-threaded)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hybrid*
may be better expressed as an interface that implements both, with mutually-recursive default methods, then from*
static methods construct concrete implementations that override either half of those mutually-recursive methods. This way you don't need to always check for what type of processor is set.
I can't see to which file is the comment pointing, but I guess this is about FlatMapProcessor, its a fix of the previous PR #1260 , its different/inner subscriber public InnerSubscriber<? super X> executeMapper(U item) {
...
}
private class InnerSubscriber<R> implements Flow.Subscriber<R> {
...
public void onNext(R o) {
Objects.requireNonNull(o);
MultiFlatMapProcessor.this.subscriber.onNext((X) o);
... |
Right, that's the place. Note that Mind you, I am not blocking the merge, just suggesting what may be a good idea to review as a future improvement. |
@olotenko Thx a lot, Hybrids with default methods are great idea, why I didn't think of it! Also thanks for generics in the flatMap. |
3b0d186
to
059a1b7
Compare
Apology for force push, needed rebase on shrinkwrap upgrade in master |
ab8fe90
to
045874c
Compare
It's just a quick fix passing tck tests so we are able to move forward, not the final solution. |
Signed-off-by: Daniel Kec <daniel.kec@oracle.com>
it is private void tryOnSubscribe() {
if (Objects.nonNull(subscription) && subscriber.tryOnSubscribe(this)) {
if (done) {
tryComplete();
}
}
} |
Hi Alex, is there any blocking issue that would prevent us from merging this pull request, or can we create a follow up issue (or issues) to fix some of your comments? |
Why did you implement operators as |
Hi @akarnokd , sure second subscribe signals onError with EDIT: wow thanks a lot, totally missed that! |
Yes, I saw those. Still, I don't see why implement operators as With a processor chain, you trigger a subscribe() storm while you are still assembling You can have simply a chain of |
If you need one example why a chain of With |
* Fix second subscriber cancellation in the BaseProcessor Signed-off-by: Daniel Kec <daniel.kec@oracle.com>
Signed-off-by: Daniel Kec <daniel.kec@oracle.com>
Signed-off-by: Daniel Kec <daniel.kec@oracle.com>
Signed-off-by: Daniel Kec <daniel.kec@oracle.com>
Signed-off-by: Daniel Kec <daniel.kec@oracle.com>
cd574d9
to
93e16d1
Compare
Include helidon-io#1429 for a known good Multi.from implementation
Multi.from can drive multiple subscribers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
How is it not emitted serially? |
|
Wrong. The atomic state transition of addRequest with requiring the transition from zero ensures there is only one thread entering the emission section. |
Well, it's more subtle than that, because it also interacts with |
Yes, the TCK expects a clear failure for non-positive request amounts which means the |
That requirement ("should not fail or complete on its own or get cancelled before that") is non-enforceable, and the code you submitted does not guarantee that either. Eg But the part where you say "should not complete or error before that" is just not enforceable. If the All the |
Yes and such bad request amounts should not go unnoticed because it means there is a bug somewhere in the chain. Since there is currently no established approach in the module to not lose exceptions, this is the best it can be done while other operators are being rewritten. We are discussing the possibility of a global error consumer on Slack.
With a general |
Yes, but you can't guarantee that after |
"global error consumer" is a "unhandled exception handler" and should be at the root of any thread. |
The reactive foundation of Helidon is currently incomplete and is not yet prepared for all corner cases within and outside the spec and the TCK. This implementation passes the TCK and enables the development of more operators.
They pose practical considerations.
If you control all the threads that may come into contact with the reactive operators. |
:) what can be more practical than fencing off problematic implementations instead of punishing everyone? Eg 3f61017#diff-6e58085854ee1341e169599585b70a21R117-R119 - you've already spent CPU cycles getting the value, you may just as well let the |
I welcome you to benchmark implementations with and without those volatile reads. |
:) simpler linear code with fewer things to think about, rather. It's not just a volatile read here, too. I get 15% difference with a iterator that just produces a range of integers. Propose a test where it matters or does not matter? |
Continuation of alternative cancelation strategy moved to /issues/1441 |
Reactive Streams Operators
Reactive Streams implementation based on existing Helidon Common Reactive Library compliant with
Reactive streams for JVM.
Part of the implementation of /issues/1206