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

Add ConnectionObserver.ProxyConnectObserver #2711

Merged
merged 1 commit into from
Sep 29, 2023

Conversation

idelpivnitskiy
Copy link
Member

@idelpivnitskiy idelpivnitskiy commented Sep 26, 2023

Motivation:

After #2699 implemented HTTP proxy CONNECT with ALPN, it made observability
confusing. It broke the contract that only one connectionEstablished method can
be invoked, which happens when ALPN switches from HTTP/1.1 to HTTP/2 pipeline.
Also, for a proxy tunnel with HTTP/1.1 ConnectionObserver events were always confusing:
users had to wait for handshakeComplete after connectionEstablished to report that
the connection is "ready".

Modifications:

  • Add ConnectionObserver.ProxyConnectObserver that reports events related to
    CONNECT phase that starts right after onTransportHandshakeComplete;
  • Refactor PipelinedLBHttpConnectionFactory to defer invocation of
    connectionEstablished/multiplexedConnectionEstablished until after the handshake
    is complete to make it consistent with non-proxied connections and make sure only
    one of the "established" methods is invoked;
  • Removed ProxyConnectLBHttpConnectionFactoryTest because it targeted code paths
    that do not exist anymore. Instead, enhanced HttpsProxyTest to cover similar use-cases.
  • Enhanced ProxyTunnel to allow behavior customization;

Result:

Enhanced observability for proxy tunnels, ConnectionObserver behavior is consistent
between proxied and non-proxied use-cases.

Expected sequence of observer callbacks:

  1. onNewConnection
  2. onTransportHandshakeComplete
  3. onProxyConnect
  4. write/flush/read
  5. proxyConnectComplete
  6. onSecurityHandshake
  7. write/flush/read
  8. handshakeComplete
  9. connectionEstablished or multiplexedConnectionEstablished, depending on ALPN results
  10. ...
  11. connectionClosed

Depends on #2699, review only starting from "Add ConnectionObserver.ProxyConnectObserver" commit.

@idelpivnitskiy idelpivnitskiy self-assigned this Sep 26, 2023
Copy link
Contributor

@daschl daschl left a comment

Choose a reason for hiding this comment

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

let's 🚢

@@ -71,6 +72,11 @@ public void onFlush() {
public void onTransportHandshakeComplete() {
}

@Override
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe for a follow-up pr: but why do we have NoopTransportObservers in transport internal and transport api? Maybe we can make the internal one use the one in API?

Copy link
Member Author

Choose a reason for hiding this comment

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

The original motivation was to avoid null-checks in our internal codebase, but overtime we found it not user-friendly to always require to return an observer. Users struggle to understand what they suppose to return when they are not interested in callbacks of sub-observer. Even if we make it public in transport-api, it's still hard to discover and easy to return your own, which will not give expected reduction of the overhead. The long-term plan is to make all callbacks that return another observer @Nullable.

Motivation:

After apple#2699 implemented HTTP proxy CONNECT with ALPN, it made observability
confusing. It broke the contract that only one `connectionEstablished` method can
be invoked, which happens when ALPN switches from HTTP/1.1 to HTTP/2 pipeline.
Also, for a proxy tunnel with HTTP/1.1 `ConnectionObserver` events were always confusing:
users had to wait for `handshakeComplete` after `connectionEstablished` to report that
the connection is "ready".

Modifications:

- Add `ConnectionObserver.ProxyConnectObserver` that reports events related to
`CONNECT` phase that starts right after `onTransportHandshakeComplete`;
- Refactor `PipelinedLBHttpConnectionFactory` to defer invocation of
`connectionEstablished`/`multiplexedConnectionEstablished` until after the handshake
is complete to make it consistent with non-proxied connections and make sure only
one of the "established" methods is invoked;
- Removed `ProxyConnectLBHttpConnectionFactoryTest` because it targeted code paths
that do not exist anymore. Instead, enhanced `HttpsProxyTest` to cover similar use-cases.
- Enhanced `ProxyTunnel` to allow behavior customization;

Result:

Enhanced observability for proxy tunnels, `ConnectionObserver` behavior is consistent
between proxied and non-proxied use-cases.
@idelpivnitskiy idelpivnitskiy merged commit 66f838c into apple:main Sep 29, 2023
15 checks passed
@idelpivnitskiy idelpivnitskiy deleted the ProxyConnectObserver branch September 29, 2023 20:04
idelpivnitskiy added a commit to idelpivnitskiy/servicetalk that referenced this pull request Oct 2, 2023
Motivation:

Prior to `ConnectionObserver.ProxyConnectObserver` added in apple#2711, the
sequence of `ConnectionObserver` events was different between regular
connections and connection to the proxy tunnels.
`HttpContextKeys.HTTP_TARGET_ADDRESS_BEHIND_PROXY` (apple#2169) was useful to
distinguish when the correct callback inside `ConnectionObserver` before
reporting that a new connection is ready to take traffic.
After adding `ProxyConnectObserver`, there is no need in this custom
key.

Modifications:

- Deprecate `HttpContextKeys.HTTP_TARGET_ADDRESS_BEHIND_PROXY` and
describe what is an appropriate replacement for users;

Result:

We will be able to remove
`HttpContextKeys.HTTP_TARGET_ADDRESS_BEHIND_PROXY` in the future
releases.
idelpivnitskiy added a commit that referenced this pull request Oct 3, 2023
Motivation:

Prior to `ConnectionObserver.ProxyConnectObserver` added in #2711, the
sequence of `ConnectionObserver` events was different between regular
connections and connection to the proxy tunnels.
`HttpContextKeys.HTTP_TARGET_ADDRESS_BEHIND_PROXY` (#2169) was useful to
distinguish when the correct callback inside `ConnectionObserver` before
reporting that a new connection is ready to take traffic.
After adding `ProxyConnectObserver`, there is no need in this custom
key.

Modifications:

- Deprecate `HttpContextKeys.HTTP_TARGET_ADDRESS_BEHIND_PROXY` and
describe what is an appropriate replacement for users;

Result:

We will be able to remove
`HttpContextKeys.HTTP_TARGET_ADDRESS_BEHIND_PROXY` in the future
releases.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants