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

Issue #12266 - InvocationType improvements and cleanups. #12596

Open
wants to merge 15 commits into
base: jetty-12.1.x
Choose a base branch
from

Conversation

sbordet
Copy link
Contributor

@sbordet sbordet commented Nov 29, 2024

This is the work for the client-side.

Now the InvocationType can be specified at the HttpClientTransport level, or at the ClientConnectionFactory.Info level (for the dynamic transport).

Wired the InvocationType also for Response.ContentSourceListener, so that for applications that read response content using Content.Source and specify an InvocationType to demand(Runnable), the implementation will honor it.

This is the work for the client-side.

Now the `InvocationType` can be specified at the `HttpClientTransport` level, or at the `ClientConnectionFactory.Info` level (for the dynamic transport).

Wired the `InvocationType` also for `Response.ContentSourceListener`, so that for applications that read response content using `Content.Source` and specify an `InvocationType` to `demand(Runnable)`, the implementation will honor it.

Signed-off-by: Simone Bordet <[email protected]>
@sbordet sbordet requested review from gregw and lorban November 29, 2024 14:10
@sbordet sbordet linked an issue Nov 29, 2024 that may be closed by this pull request
Simplified retrieval of InvocationType, now only available from the HttpClientTransport.

Signed-off-by: Simone Bordet <[email protected]>
…case of content not yet arrived.

Signed-off-by: Simone Bordet <[email protected]>
Before, `Stream.Listener.onHeaders()` was assuming that the headers were processed synchronously.
Now, `HttpReceiverOverHTTP2` process them asynchronously, with a task that declares an invocation type.
This was causing a race between the task and the code present after the call to `onHeaders()`.

Introduced `Stream.Listener.onHeaders(Stream, HeadersFrame, Callback)` to allow asynchronous processing of `HeadersFrame`s.

Optimised `HttpReceiver.responseHeaders()` to avoid creating the `Content.Source` if there is no content.

Fixed `IteratingCallback` and `HTTP2Flusher` to use `tryLock()` in `toString()` to avoid deadlocks.

Signed-off-by: Simone Bordet <[email protected]>
void setConnectionPoolFactory(ConnectionPool.Factory factory);

/**
* @return the {@link InvocationType} associated with this {@code HttpClientTransport}.
Copy link
Contributor

Choose a reason for hiding this comment

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

The javadoc should explain that the invocation type is going to be used to figure out how to execute the listeners.

public InvocationType getInvocationType()
{
Runnable demandCallback = demandCallbackRef.get();
if (demandCallback == null)
Copy link
Contributor

Choose a reason for hiding this comment

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

There should definitely be a comment explaining why we return the connection's invocation type when the demand callback is null, as that's quite a special trick for which I already forgot the details of.

@@ -188,7 +188,7 @@ interface AsyncContentListener extends ContentSourceListener
@Override
default void onContentSource(Response response, Content.Source contentSource)
{
Runnable demandCallback = Invocable.from(Invocable.InvocationType.NON_BLOCKING, () -> onContentSource(response, contentSource));
Runnable demandCallback = Invocable.from(Invocable.getInvocationType(contentSource), () -> onContentSource(response, contentSource));
Copy link
Contributor

Choose a reason for hiding this comment

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

There should probably be a comment explaining why we use the invocation type of the content source: how this trick exactly works is easy to forget.

@@ -116,4 +120,48 @@ public String toString()
sender,
receiver);
}

private class Listener implements Stream.Client.Listener
Copy link
Contributor

Choose a reason for hiding this comment

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

The executions of the runnable desserve to be documented.

boolean held = lock.isHeldByCurrentThread();
return String.format("%s@%x{handling=%s, handled=%s, send=%s, completed=%s, request=%s}",
String held = lock.isHeldByCurrentThread() ? "" : "?";
return String.format("%s@%x[%s:handling=%s,handled=%s,send=%s,completed=%s,request=%s]",
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the : should be part of the held string.

response.write(false, null, Callback.NOOP);
// Wait to force the client to invoke the content
// callback separately from the headers callback.
Thread.sleep(500);
Copy link
Contributor

Choose a reason for hiding this comment

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

No sleep please; it's better to wait until the headers event has been called.

{
return String.format("%s@%x[%s, %b, %s]", getClass().getSimpleName(), hashCode(), _state, _aborted, _failure);
String held = _lock.isHeldByCurrentThread() ? "" : "?";
Copy link
Contributor

Choose a reason for hiding this comment

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

: should be in the held string.

@sbordet sbordet added this to the ! milestone Dec 12, 2024
Fixed reset race in HTTP2Stream.

Signed-off-by: Simone Bordet <[email protected]>
Signed-off-by: Simone Bordet <[email protected]>
Signed-off-by: Simone Bordet <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: 👀 In review
Development

Successfully merging this pull request may close these issues.

InvocationType improvements and cleanups
2 participants