-
Notifications
You must be signed in to change notification settings - Fork 181
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
SpliceFlatStreamToMetaSingle
: propagate cancel when races with data
#3036
Conversation
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.
Ready for review, but will be merged only after Single.ambWith(...)
fix
@@ -67,6 +68,7 @@ | |||
import static org.hamcrest.Matchers.startsWith; | |||
import static org.junit.jupiter.api.Assertions.assertThrows; | |||
|
|||
@Disabled // FIXME: remove before merging |
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.
This PR is blocked by awaiting a fix for Single.ambWith(...)
operator
if (maybePayloadSubUpdater.compareAndSet(this, null, CANCELED)) { | ||
final Object current = maybePayloadSubUpdater.getAndUpdate(this, | ||
curr -> curr == null || curr == PENDING ? CANCELED : curr); | ||
if (current == null || current == PENDING) { |
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.
Please carefully review the updated state machine and existing tests that we have. If you see a use-case not covered by the tests, will appreciate new ideas.
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.
Looks good but it's complex code so I'd recommend getting one more review before merging.
...icetalk-http-netty/src/main/java/io/servicetalk/http/netty/SpliceFlatStreamToMetaSingle.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.
lgtm after ignored test is brought back to working
Motivation:
Cancellation of the single may race with delivering the first element. If
cancel
wins, we already deliverCancellationException
if someone subscribes to the payload publisher. However, ifcancel
arrives afterdataSubscriber.onSuccess(...)
and before someone subscribes to the payload publisher, it's a strong indicator that there was a race anddataSubscriber
is not interested in it anymore. Therefore, we should pessimistically assume that nobody will ever subscribe to the payload publisher, cancel upstream subscription, and deliverCancellationException
is someone still subscribes.Modifications:
null
andPENDING
states if received data cancel;parent.packer.apply
to assert that this path happens only ifCANCELED
;CancellationException
is someone still subscribes to the payload publisher afterCANCELED
;dataSubscriber.onError
ifmetaSeenInOnNext == true
because it's already terminated (CANCELED
does not play any role here);payloadSubscriber
is already terminated (EMPTY_COMPLETED_DELIVERED
);Result:
Network resources receive
cancel
signal and clean up connection state.Note that the original version of this operator had this behavior, but it was changed in 38e2c67
We don't have a full PR for that commit with review comments. Based on the commit description I believe it was fixing a different problem and the change in cancel propagation behavior for
PENDING
state is likely a side-effect of introducing a new state.