Skip to content
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

Experiment with IteratingCallback #12040

Merged
merged 34 commits into from
Aug 26, 2024

Conversation

gregw
Copy link
Contributor

@gregw gregw commented Jul 15, 2024

The previous semantic of onCompleteFailure has been renamed to onFailure(Throwable), which is called immediately (but serialized) on either an abort or a failure. A new onCompleteFailure(Throwable) method has been added that is called only after a failed(throwable) or a abort(Throwable) followed by succeeded() or `failed(Throwable)``

No usage has yet been made of the new onCompleteFailure, but the ICB implementation has been completely replaced by the one developed in #11876

The previous semantic of `onCompleteFailure` has been renamed to `onFailure(Throwable)`, which is called immediately (but serialized) on either an abort or a failure.   A new `onCompleteFailure(Throwable)` method has been added that is called only after a `failed(throwable)` or a `abort(Throwable)` followed by `succeeded()` or `failed(Throwable)``

No usage has yet been made of the new `onCompleteFailure`, but the ICB implementation has been completely replaced by the one developed in #11876
@gregw gregw requested review from sbordet and lorban July 15, 2024 08:18
lorban
lorban previously requested changes Jul 15, 2024
Copy link
Contributor

@lorban lorban left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO the onCompleteXyz trio should be improved to leave no trace to confusion in the API. Otherwise LGTM.

The previous semantic of `onCompleteFailure` has been renamed to `onFailure(Throwable)`, which is called immediately (but serialized) on either an abort or a failure.   A new `onCompleteFailure(Throwable)` method has been added that is called only after a `failed(throwable)` or a `abort(Throwable)` followed by `succeeded()` or `failed(Throwable)``

No usage has yet been made of the new `onCompleteFailure`, but the ICB implementation has been completely replaced by the one developed in #11876
@gregw gregw requested a review from lorban July 16, 2024 01:28
The previous semantic of `onCompleteFailure` has been renamed to `onFailure(Throwable)`, which is called immediately (but serialized) on either an abort or a failure.   A new `onCompleteFailure(Throwable)` method has been added that is called only after a `failed(throwable)` or a `abort(Throwable)` followed by `succeeded()` or `failed(Throwable)``

No usage has yet been made of the new `onCompleteFailure`, but the ICB implementation has been completely replaced by the one developed in #11876
Copy link
Contributor

@sbordet sbordet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is way too fine-grained.

I would be fine to "delay" the call to onCompleteFailure() until completeness (rather than early failure), and that's it.

The new methods introduced are currently not used, and will be APIs that we need to maintain and carefully document about what can and cannot be done in them, which I think is a big effort not worth it.
Their semantic is delicate and we got it mostly wrong in this PR (e.g. calling release from onFailure()).

So I'd revert to minimal changes, i.e. just "delay" properly the call to onCompleteFailure(), and all the rest should just be correct as it is.

sbordet
sbordet previously approved these changes Jul 19, 2024
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This is necessary to avoid confusion, for example class A_ICB extending ICB and overriding onCompleted() without calling super, and class B_ICB extending A_ICB and overriding onCompleteSuccess() which would be never called.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
@sbordet
Copy link
Contributor

sbordet commented Jul 19, 2024

@gregw I think it is mandatory that "release" operations in case of failure become in fact "remove" operations, when dealing with buffers, because it is always possible that the failure is asynchronous, and the buffer is being utilized by the async operation while the release is trying to put it back into the pool for reuse.
It cannot be reused.

Therefore, rather than splitting the "fail" and "release" operations, the former in onFailure() and the latter in onCompleteFailure() (which I have done as an experiment in in branch experiment/jetty-12.1.x/IteratingCallback-SplitRelease), we should instead do the "fail" and "remove" actions from onFailure().

Which then begs the question if we need to have the additional methods introduced in this PR especially regarding abort/failure.
The reason is that current code overriding onCompleteFailure() would have a different behavior with this PR, possibly breaking users like #12055 showed.

So the idea is to have onCompleteFailure() behave like it always did, but fix the "release" operations in case of failure with "remove" operations, and not add the new methods such as onAborted(), onFailed(), etc.

Or, we bit the bullet, change the behavior in 12.1.x, introduce the new methods, possibly break existing code, but avoid the split of my experiment PR by introducing "remove" semantic to RBB.

@sbordet sbordet self-requested a review July 19, 2024 14:28
@sbordet sbordet dismissed their stale review July 19, 2024 14:29

Dismissing after additional discussions with @lorban.

@gregw
Copy link
Contributor Author

gregw commented Jul 21, 2024

@lorban Since #12055 has been closed by @sbordet, can we review this one. The aim here is to provide the option for the new semantic, with better naming, but to not change behaviour. Behavior changes can be done bit by bit in subsequent PRs.

@gregw
Copy link
Contributor Author

gregw commented Jul 26, 2024

@lorban can you take this one on?

@sbordet
Copy link
Contributor

sbordet commented Aug 2, 2024

@gregw a note to self/team about failures in case of non termination.

The practical example would be a write that is TCP congested, and a timeout happening.

onFailure() would be called, but the write won't complete unless TCP congestion resolves, or the endPoint is closed in onFailure() (I assume that closing the endPoint would fail the write, but needs to be tested).

@gregw
Copy link
Contributor Author

gregw commented Aug 2, 2024

@gregw a note to self/team about failures in case of non termination.

The practical example would be a write that is TCP congested, and a timeout happening.

onFailure() would be called, but the write won't complete unless TCP congestion resolves, or the endPoint is closed in onFailure() (I assume that closing the endPoint would fail the write, but needs to be tested).

@sbordet ... and further to that example, we have two strategies to deal with the scenario:

a) in onFailure we remove the write buffer from the pooling, so that it will not be reused ever.
b) we move releasing the write the write buffer to onCompleteFailure, so it is reused, but only once the congestion is resolved and the write completes (or fails)

The buffer is held in memory in both a) and b), so there is no memory saving in either. In a) we potentially free a slot in the buffer pool making for better pooling for other requests, but only a very marginal gain. So the choice between a) and b) really should be based on code clarity and what other events might be triggered by onFailure and/or onCompleteFailure. I think both are valid, so we should make remove() a first class operation on RBB

…gCallback-SplitRelease' into experiment/jetty-12.1.x/IteratingCallback

# Conflicts:
#	documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/ContentDocs.java
#	jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/HTTP2Flusher.java
#	jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipResponseAndCallback.java
#	jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/HttpOutput.java
#	jetty-ee11/jetty-ee11-servlet/src/main/java/org/eclipse/jetty/ee11/servlet/HttpOutput.java
#	jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HttpOutput.java
@gregw gregw requested a review from sbordet August 6, 2024 23:33
@lorban
Copy link
Contributor

lorban commented Aug 7, 2024

FYI HttpClientStreamTest.testInputStreamContentProviderThrowingWhileReading() seems to fail because of a leak introduced in FCGI.

gregw and others added 6 commits August 8, 2024 07:03
…lback

# Conflicts:
#	jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/HttpOutput.java
#	jetty-ee11/jetty-ee11-servlet/src/main/java/org/eclipse/jetty/ee11/servlet/HttpOutput.java
Signed-off-by: Ludovic Orban <lorban@bitronix.be>
Signed-off-by: Ludovic Orban <lorban@bitronix.be>
Signed-off-by: Ludovic Orban <lorban@bitronix.be>
@sbordet sbordet self-requested a review August 13, 2024 15:02
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
@gregw
Copy link
Contributor Author

gregw commented Aug 22, 2024

@sbordet are you OK if I dismiss @lorban's review and merge this once I get a build clean of flakes?

@sbordet
Copy link
Contributor

sbordet commented Aug 23, 2024

@gregw I'm ok to merge this.

@gregw
Copy link
Contributor Author

gregw commented Aug 26, 2024

The QoSHandler CI failures appear to be a problem in head, so merging this without a green build.

@gregw gregw merged commit 7d7eeb3 into jetty-12.1.x Aug 26, 2024
5 of 10 checks passed
@gregw gregw deleted the experiment/jetty-12.1.x/IteratingCallback branch August 26, 2024 00:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: ✅ Done
Development

Successfully merging this pull request may close these issues.

3 participants