-
Notifications
You must be signed in to change notification settings - Fork 909
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
HttpResponse.of(ResponseHeaders,Publisher<HttpObject>) #3237
Conversation
Not sure why this happens, it seems irrelevant 😄
|
Please forget about it. It's a flaky test. 😅 |
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.
Nice! Sorry for a late review, @tumile. Have a great holiday ☃️
core/src/main/java/com/linecorp/armeria/common/HttpResponse.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/common/PublisherBasedHttpResponse.java
Outdated
Show resolved
Hide resolved
Codecov Report
@@ Coverage Diff @@
## master #3237 +/- ##
============================================
+ Coverage 74.11% 74.13% +0.01%
- Complexity 12873 13244 +371
============================================
Files 1119 1158 +39
Lines 48746 50367 +1621
Branches 6229 6442 +213
============================================
+ Hits 36129 37339 +1210
- Misses 9437 9741 +304
- Partials 3180 3287 +107
Continue to review full report at Codecov.
|
@trustin Hope you and the team have a great holiday too! And hope that Armeria has another year of wonderful growth! But to start it out we have another |
Sorry about the inconveniences. 😢 It's because we want to refer to some type information in our documentation. |
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.
👍
core/src/main/java/com/linecorp/armeria/common/PublisherBasedHttpResponse.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/common/PublisherBasedHttpResponse.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/common/PublisherBasedHttpResponse.java
Outdated
Show resolved
Hide resolved
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.
Left some comments that violate Reactive Streams Specifications. Those things could be checked by Reactive Streams TCK.
core/src/main/java/com/linecorp/armeria/internal/common/stream/PrependingPublisher.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/internal/common/stream/PrependingPublisher.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/internal/common/stream/PrependingPublisher.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/internal/common/stream/PrependingPublisher.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/internal/common/stream/PrependingPublisher.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/internal/common/stream/PrependingPublisher.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/internal/common/stream/PrependingPublisher.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/internal/common/stream/PrependingPublisher.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/internal/common/stream/PrependingPublisher.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/internal/common/stream/PrependingPublisher.java
Outdated
Show resolved
Hide resolved
core/src/test/java/com/linecorp/armeria/internal/common/stream/PrependingPublisherTckTest.java
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/internal/common/stream/PrependingPublisher.java
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/common/HttpResponse.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/common/HttpResponse.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/common/PublisherBasedHttpResponse.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/internal/common/stream/PrependingPublisher.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/internal/common/stream/PrependingPublisher.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/internal/common/stream/PrependingPublisher.java
Outdated
Show resolved
Hide resolved
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.
Still LGTM, once @minwoox's comments are addressed.
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.
Nice work! @tumile
core/src/main/java/com/linecorp/armeria/internal/common/stream/PrependingPublisher.java
Outdated
Show resolved
Hide resolved
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.
I think we are almost there. 😄
core/src/main/java/com/linecorp/armeria/internal/common/stream/PrependingPublisher.java
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/internal/common/stream/PrependingPublisher.java
Outdated
Show resolved
Hide resolved
final long demand = this.demand; | ||
final long newDemand = demand >= Long.MAX_VALUE - n ? Long.MAX_VALUE : demand + n; | ||
if (demandUpdater.compareAndSet(this, demand, newDemand)) { | ||
if (demand > 0) { |
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.
Shouldn't we just remove this condition?
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.
We check this because if the previous demand
is non-zero then there is already an ongoing request and we stop, otherwise it could lead to unbounded recursion request -> onNext -> request ->...
. If I remove this rule 3.3 will fail 😄 .
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.
Oops could you elaborate more on request -> onNext -> request ->...
, please?
If we just return here, there's a chance the upstream.request(...)
is not called.
Let's say that thread A calls Subscription.request(2)
twice.
When the second Subscription.request(2)
is called and if it's at line 84.
Meanwhile, thread B is trying demandUpdater.compareAndSet(this, demand, 0)
at line 138.
If the thread B fails to compareAndSet, then thread A might set the demand as 3 and there's no more upstream.request(demand);
call
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.
Could the race condition be solved by adding a for loop in onSubscribe()
?
// Keep retrying to send a request signal until demain is zero
for (;;) {
final long demand = this.demand;
if (demand == 0) {
break;
}
if (demandUpdater.compareAndSet(this, demand, 0)) {
subscription.request(demand);
}
}
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.
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.
I probably might get this wrong, 😄 but if's it's for guarding a stack overflow,
what happens when the thread calls upstream.request(demand)
here?https://github.com/line/armeria/pull/3237/files#diff-a8dfc683de291a0ccbc6e0ab3c2bae463e462050ac18beca18b3adf6c14c1b5fR110
Isn't it the same?
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.
Right, I get what you say 😄 . The condition is there to satisfy the TCK, which assumes the calls are on the same thread. In fact rule 3.3 just "recommended" the stack depth to be 1. I don't think in practice we would overflow by any means, especially in Armeria.
core/src/main/java/com/linecorp/armeria/internal/common/stream/PrependingPublisher.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/internal/common/stream/PrependingPublisher.java
Outdated
Show resolved
Hide resolved
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.
Anyway, thanks a lot for your patience, @tumile. 😄
Thanks everyone! I didn't think this could turn out to be so complicated. Couldn't have finished it without your support 🙇 |
Neither did I. 🤣 |
Motivation:
Provide an easy way to build a
HttpResponse
withResponseHeaders
and aPublisher<HttpObject>
.Modifications:
Added
PrependingPublisher
that can prepend an object to aPublisher
of the same type.Result:
Closes #3089