Skip to content

[refactor][proxy] Refactor Proxy code and fix connection stalling by switching to auto read mode - #14713

Merged
codelipenghui merged 9 commits into
apache:masterfrom
lhotari:lh-refactor-proxy-code
Mar 22, 2022
Merged

[refactor][proxy] Refactor Proxy code and fix connection stalling by switching to auto read mode#14713
codelipenghui merged 9 commits into
apache:masterfrom
lhotari:lh-refactor-proxy-code

Conversation

@lhotari

@lhotari lhotari commented Mar 16, 2022

Copy link
Copy Markdown
Member

Motivation

Refactor Proxy code to make it easier to understand and maintain. In addition, switch to use auto read mode since the proxies connections seem to stall in some cases since the proxied connection doesn't use Netty's auto read mode and the read handling doesn't seem complete.

Currently, the proxy calls .read() when a message is written to the connection. There might be more messages flowing in the other direction and it could result in a blocked connection with the current solution that doesn't use Netty's auto read mode.

Currently auto read is disabled in DirectProxyHandler for the connection between the proxy and the broker:

b.group(inboundChannel.eventLoop()).channel(inboundChannel.getClass()).option(ChannelOption.AUTO_READ, false);

Modifications

  • replace broker host parsing with a simple solution
  • pass remote host name to ProxyBackendHandler in the constructor
  • rename "targetBrokerUrl" to "brokerHostAndPort" since the "targetBrokerUrl" is really "hostname:port" string
  • move HA proxy message handling to ProxyBackendHandle and extract the logic to a method
  • remove the static "inboundOutboundChannelMap" which was used for log level 2
    • make it obsolete by passing the peer channel id to ParserProxyHandler
  • Enable auto read in proxy and remove ctx.read() / channel.read() calls
  • prepare for IPv6 support (reported as IPv6 Support for broker and proxy with bindAddress #14732) by improving the host:port parsing (pick last : since IPv6 address might contains multiple : characters)
  • Handle backpressure properly by switching auto read off when channel writability changes
    • change auto read of the proxy-broker connection based on the writability of the client-proxy connection
    • change auto read of the client-proxy connection based on the writability of the proxy-broker connection
  • Consistently handle write errors by delegating exception handling to exceptionCaught method by using .addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)

@lhotari lhotari added area/proxy doc-not-needed Your PR changes do not impact docs labels Mar 16, 2022
@lhotari lhotari self-assigned this Mar 16, 2022

@michaeljmarshall michaeljmarshall left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@michaeljmarshall michaeljmarshall added the type/cleanup Code or doc cleanups e.g. remove the outdated documentation or remove the code no longer in use label Mar 16, 2022
@michaeljmarshall michaeljmarshall added this to the 2.11.0 milestone Mar 16, 2022

@eolivelli eolivelli left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nice and useful work !

@eolivelli

Copy link
Copy Markdown
Contributor

@lhotari please resolve the conflicts

@lhotari
lhotari force-pushed the lh-refactor-proxy-code branch from 3c3c40e to 4a24061 Compare March 17, 2022 11:22
@lhotari
lhotari marked this pull request as draft March 17, 2022 11:53
@lhotari lhotari changed the title [Proxy] Refactor Proxy code [Proxy] Refactor Proxy code and fix connection stalling by switching to auto read mode Mar 17, 2022
@lhotari
lhotari marked this pull request as ready for review March 17, 2022 16:06
@lhotari

lhotari commented Mar 17, 2022

Copy link
Copy Markdown
Member Author

I ended up increasing the scope of this PR and added the fix to a connection stalling issue. Please review again @eolivelli @codelipenghui @michaeljmarshall @nicoloboschi @merlimat

@eolivelli eolivelli left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

+1

Comment thread pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/DirectProxyHandler.java Outdated
@lhotari
lhotari marked this pull request as draft March 17, 2022 16:31
@lhotari

lhotari commented Mar 17, 2022

Copy link
Copy Markdown
Member Author

I asked for feedback in the community meeting from @merlimat . Based on the discussion there was the conclusion that backpressure is needed to prevent a situation where the proxy buffers grow in the case where either the broker connection is slow or the client connection is slow.

…ity changes

- change auto read of the proxy-broker connection based on the writability of the
  client-proxy connection
- change auto read of the client-proxy connection based on the writability of the
  proxy-broker connection
@lhotari
lhotari marked this pull request as ready for review March 17, 2022 17:09
@lhotari

lhotari commented Mar 17, 2022

Copy link
Copy Markdown
Member Author

@merlimat I have implemented the solution for flow control in a04aa5f . Please review

@lhotari

lhotari commented Mar 17, 2022

Copy link
Copy Markdown
Member Author

The channel writability change feature in Netty can be configured with setWriteBufferWaterMark or setWriteBufferLowWaterMark/setWriteBufferHighWaterMark methods. By default, the low water mark is 32kB and high water mark is 64kB. That sounds like a sensible default.

@lhotari lhotari added the type/bug The PR fixed a bug or issue reported a bug label Mar 18, 2022
- delegate exception handling to exceptionCaught method

@michaeljmarshall michaeljmarshall left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@codelipenghui
codelipenghui merged commit a1037c7 into apache:master Mar 22, 2022
@codelipenghui codelipenghui changed the title [Proxy] Refactor Proxy code and fix connection stalling by switching to auto read mode [refactor][proxy] Refactor Proxy code and fix connection stalling by switching to auto read mode Mar 22, 2022
lhotari added a commit to datastax/pulsar that referenced this pull request Mar 22, 2022
…switching to auto read mode (apache#14713)

Refactor Proxy code to make it easier to understand and maintain. In addition, switch to use auto read mode since the proxies connections seem to stall in some cases since the proxied connection doesn't use Netty's auto read mode and the read handling doesn't seem complete.

Currently, the proxy calls `.read()` when a message is written to the connection. There might be more messages flowing in the other direction and it could result in a blocked connection with the current solution that doesn't use Netty's auto read mode.

Currently auto read is disabled in DirectProxyHandler for the connection between the proxy and the broker:
https://github.com/apache/pulsar/blob/a26905371749798ec5288fb07a69978a36aacfaa/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/DirectProxyHandler.java#L112

- replace broker host parsing with a simple solution
- pass remote host name to ProxyBackendHandler in the constructor
- rename "targetBrokerUrl" to "brokerHostAndPort" since the "targetBrokerUrl" is really "hostname:port" string
- move HA proxy message handling to ProxyBackendHandle and extract the logic to a method
- remove the static "inboundOutboundChannelMap" which was used for log level 2
  - make it obsolete by passing the peer channel id to ParserProxyHandler
 - Enable auto read in proxy and remove `ctx.read()` / `channel.read()` calls
- prepare for IPv6 support (reported as apache#14732) by improving the `host:port` parsing (pick last `:` since IPv6 address might contains multiple `:` characters)
- Handle backpressure properly by switching auto read off when channel writability changes
  - change auto read of the proxy-broker connection based on the writability of the client-proxy connection
  - change auto read of the client-proxy connection based on the writability of the proxy-broker connection
- Consistently handle write errors by delegating exception handling to exceptionCaught method by using `.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)`

(cherry picked from commit a1037c7)
lhotari added a commit to datastax/pulsar that referenced this pull request Mar 22, 2022
…switching to auto read mode (apache#14713)

Refactor Proxy code to make it easier to understand and maintain. In addition, switch to use auto read mode since the proxies connections seem to stall in some cases since the proxied connection doesn't use Netty's auto read mode and the read handling doesn't seem complete.

Currently, the proxy calls `.read()` when a message is written to the connection. There might be more messages flowing in the other direction and it could result in a blocked connection with the current solution that doesn't use Netty's auto read mode.

Currently auto read is disabled in DirectProxyHandler for the connection between the proxy and the broker:
https://github.com/apache/pulsar/blob/a26905371749798ec5288fb07a69978a36aacfaa/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/DirectProxyHandler.java#L112

- replace broker host parsing with a simple solution
- pass remote host name to ProxyBackendHandler in the constructor
- rename "targetBrokerUrl" to "brokerHostAndPort" since the "targetBrokerUrl" is really "hostname:port" string
- move HA proxy message handling to ProxyBackendHandle and extract the logic to a method
- remove the static "inboundOutboundChannelMap" which was used for log level 2
  - make it obsolete by passing the peer channel id to ParserProxyHandler
 - Enable auto read in proxy and remove `ctx.read()` / `channel.read()` calls
- prepare for IPv6 support (reported as apache#14732) by improving the `host:port` parsing (pick last `:` since IPv6 address might contains multiple `:` characters)
- Handle backpressure properly by switching auto read off when channel writability changes
  - change auto read of the proxy-broker connection based on the writability of the client-proxy connection
  - change auto read of the client-proxy connection based on the writability of the proxy-broker connection
- Consistently handle write errors by delegating exception handling to exceptionCaught method by using `.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)`

(cherry picked from commit a1037c7)
lhotari added a commit to datastax/pulsar that referenced this pull request Mar 22, 2022
…switching to auto read mode (apache#14713)

### Motivation

Refactor Proxy code to make it easier to understand and maintain. In addition, switch to use auto read mode since the proxies connections seem to stall in some cases since the proxied connection doesn't use Netty's auto read mode and the read handling doesn't seem complete.

Currently, the proxy calls `.read()` when a message is written to the connection. There might be more messages flowing in the other direction and it could result in a blocked connection with the current solution that doesn't use Netty's auto read mode.

Currently auto read is disabled in DirectProxyHandler for the connection between the proxy and the broker:
https://github.com/apache/pulsar/blob/a26905371749798ec5288fb07a69978a36aacfaa/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/DirectProxyHandler.java#L112


### Modifications

- replace broker host parsing with a simple solution
- pass remote host name to ProxyBackendHandler in the constructor
- rename "targetBrokerUrl" to "brokerHostAndPort" since the "targetBrokerUrl" is really "hostname:port" string
- move HA proxy message handling to ProxyBackendHandle and extract the logic to a method
- remove the static "inboundOutboundChannelMap" which was used for log level 2
  - make it obsolete by passing the peer channel id to ParserProxyHandler
 - Enable auto read in proxy and remove `ctx.read()` / `channel.read()` calls
- prepare for IPv6 support (reported as apache#14732) by improving the `host:port` parsing (pick last `:` since IPv6 address might contains multiple `:` characters)
- Handle backpressure properly by switching auto read off when channel writability changes
  - change auto read of the proxy-broker connection based on the writability of the client-proxy connection
  - change auto read of the client-proxy connection based on the writability of the proxy-broker connection
- Consistently handle write errors by delegating exception handling to exceptionCaught method by using `.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)`

(cherry picked from commit a1037c7)

# Conflicts:
#	pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/DirectProxyHandler.java
#	pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ParserProxyHandler.java
#	pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyConnection.java
lhotari added a commit that referenced this pull request Mar 24, 2022
…switching to auto read mode (#14713)

### Motivation

Refactor Proxy code to make it easier to understand and maintain. In addition, switch to use auto read mode since the proxies connections seem to stall in some cases since the proxied connection doesn't use Netty's auto read mode and the read handling doesn't seem complete.

Currently, the proxy calls `.read()` when a message is written to the connection. There might be more messages flowing in the other direction and it could result in a blocked connection with the current solution that doesn't use Netty's auto read mode.

Currently auto read is disabled in DirectProxyHandler for the connection between the proxy and the broker:
https://github.com/apache/pulsar/blob/a26905371749798ec5288fb07a69978a36aacfaa/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/DirectProxyHandler.java#L112

### Modifications

- replace broker host parsing with a simple solution
- pass remote host name to ProxyBackendHandler in the constructor
- rename "targetBrokerUrl" to "brokerHostAndPort" since the "targetBrokerUrl" is really "hostname:port" string
- move HA proxy message handling to ProxyBackendHandle and extract the logic to a method
- remove the static "inboundOutboundChannelMap" which was used for log level 2
  - make it obsolete by passing the peer channel id to ParserProxyHandler
 - Enable auto read in proxy and remove `ctx.read()` / `channel.read()` calls
- prepare for IPv6 support (reported as #14732) by improving the `host:port` parsing (pick last `:` since IPv6 address might contains multiple `:` characters)
- Handle backpressure properly by switching auto read off when channel writability changes
  - change auto read of the proxy-broker connection based on the writability of the client-proxy connection
  - change auto read of the client-proxy connection based on the writability of the proxy-broker connection
- Consistently handle write errors by delegating exception handling to exceptionCaught method by using `.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)`

(cherry picked from commit a1037c7)
lhotari added a commit that referenced this pull request Mar 24, 2022
…switching to auto read mode (#14713)

Refactor Proxy code to make it easier to understand and maintain. In addition, switch to use auto read mode since the proxies connections seem to stall in some cases since the proxied connection doesn't use Netty's auto read mode and the read handling doesn't seem complete.

Currently, the proxy calls `.read()` when a message is written to the connection. There might be more messages flowing in the other direction and it could result in a blocked connection with the current solution that doesn't use Netty's auto read mode.

Currently auto read is disabled in DirectProxyHandler for the connection between the proxy and the broker:
https://github.com/apache/pulsar/blob/a26905371749798ec5288fb07a69978a36aacfaa/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/DirectProxyHandler.java#L112

- replace broker host parsing with a simple solution
- pass remote host name to ProxyBackendHandler in the constructor
- rename "targetBrokerUrl" to "brokerHostAndPort" since the "targetBrokerUrl" is really "hostname:port" string
- move HA proxy message handling to ProxyBackendHandle and extract the logic to a method
- remove the static "inboundOutboundChannelMap" which was used for log level 2
  - make it obsolete by passing the peer channel id to ParserProxyHandler
 - Enable auto read in proxy and remove `ctx.read()` / `channel.read()` calls
- prepare for IPv6 support (reported as #14732) by improving the `host:port` parsing (pick last `:` since IPv6 address might contains multiple `:` characters)
- Handle backpressure properly by switching auto read off when channel writability changes
  - change auto read of the proxy-broker connection based on the writability of the client-proxy connection
  - change auto read of the client-proxy connection based on the writability of the proxy-broker connection
- Consistently handle write errors by delegating exception handling to exceptionCaught method by using `.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)`

(cherry picked from commit a1037c7)
lhotari added a commit that referenced this pull request Mar 24, 2022
…switching to auto read mode (#14713)

Refactor Proxy code to make it easier to understand and maintain. In addition, switch to use auto read mode since the proxies connections seem to stall in some cases since the proxied connection doesn't use Netty's auto read mode and the read handling doesn't seem complete.

Currently, the proxy calls `.read()` when a message is written to the connection. There might be more messages flowing in the other direction and it could result in a blocked connection with the current solution that doesn't use Netty's auto read mode.

Currently auto read is disabled in DirectProxyHandler for the connection between the proxy and the broker:
https://github.com/apache/pulsar/blob/a26905371749798ec5288fb07a69978a36aacfaa/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/DirectProxyHandler.java#L112

- replace broker host parsing with a simple solution
- pass remote host name to ProxyBackendHandler in the constructor
- rename "targetBrokerUrl" to "brokerHostAndPort" since the "targetBrokerUrl" is really "hostname:port" string
- move HA proxy message handling to ProxyBackendHandle and extract the logic to a method
- remove the static "inboundOutboundChannelMap" which was used for log level 2
  - make it obsolete by passing the peer channel id to ParserProxyHandler
 - Enable auto read in proxy and remove `ctx.read()` / `channel.read()` calls
- prepare for IPv6 support (reported as #14732) by improving the `host:port` parsing (pick last `:` since IPv6 address might contains multiple `:` characters)
- Handle backpressure properly by switching auto read off when channel writability changes
  - change auto read of the proxy-broker connection based on the writability of the client-proxy connection
  - change auto read of the client-proxy connection based on the writability of the proxy-broker connection
- Consistently handle write errors by delegating exception handling to exceptionCaught method by using `.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)`

(cherry picked from commit a1037c7)
@lhotari lhotari added cherry-picked/branch-2.8 Archived: 2.8 is end of life cherry-picked/branch-2.9 Archived: 2.9 is end of life labels Mar 24, 2022
Nicklee007 pushed a commit to Nicklee007/pulsar that referenced this pull request Apr 20, 2022
…switching to auto read mode (apache#14713)

### Motivation

Refactor Proxy code to make it easier to understand and maintain. In addition, switch to use auto read mode since the proxies connections seem to stall in some cases since the proxied connection doesn't use Netty's auto read mode and the read handling doesn't seem complete.

Currently, the proxy calls `.read()` when a message is written to the connection. There might be more messages flowing in the other direction and it could result in a blocked connection with the current solution that doesn't use Netty's auto read mode. 

Currently auto read is disabled in DirectProxyHandler for the connection between the proxy and the broker: 
https://github.com/apache/pulsar/blob/a26905371749798ec5288fb07a69978a36aacfaa/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/DirectProxyHandler.java#L112


### Modifications

- replace broker host parsing with a simple solution
- pass remote host name to ProxyBackendHandler in the constructor
- rename "targetBrokerUrl" to "brokerHostAndPort" since the "targetBrokerUrl" is really "hostname:port" string
- move HA proxy message handling to ProxyBackendHandle and extract the logic to a method
- remove the static "inboundOutboundChannelMap" which was used for log level 2 
  - make it obsolete by passing the peer channel id to ParserProxyHandler
 - Enable auto read in proxy and remove `ctx.read()` / `channel.read()` calls
- prepare for IPv6 support (reported as apache#14732) by improving the `host:port` parsing (pick last `:` since IPv6 address might contains multiple `:` characters)
- Handle backpressure properly by switching auto read off when channel writability changes
  - change auto read of the proxy-broker connection based on the writability of the client-proxy connection
  - change auto read of the client-proxy connection based on the writability of the proxy-broker connection
- Consistently handle write errors by delegating exception handling to exceptionCaught method by using `.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)`
dlg99 pushed a commit to dlg99/pulsar that referenced this pull request May 16, 2022
…switching to auto read mode (apache#14713)

Refactor Proxy code to make it easier to understand and maintain. In addition, switch to use auto read mode since the proxies connections seem to stall in some cases since the proxied connection doesn't use Netty's auto read mode and the read handling doesn't seem complete.

Currently, the proxy calls `.read()` when a message is written to the connection. There might be more messages flowing in the other direction and it could result in a blocked connection with the current solution that doesn't use Netty's auto read mode.

Currently auto read is disabled in DirectProxyHandler for the connection between the proxy and the broker:
https://github.com/apache/pulsar/blob/a26905371749798ec5288fb07a69978a36aacfaa/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/DirectProxyHandler.java#L112

- replace broker host parsing with a simple solution
- pass remote host name to ProxyBackendHandler in the constructor
- rename "targetBrokerUrl" to "brokerHostAndPort" since the "targetBrokerUrl" is really "hostname:port" string
- move HA proxy message handling to ProxyBackendHandle and extract the logic to a method
- remove the static "inboundOutboundChannelMap" which was used for log level 2
  - make it obsolete by passing the peer channel id to ParserProxyHandler
 - Enable auto read in proxy and remove `ctx.read()` / `channel.read()` calls
- prepare for IPv6 support (reported as apache#14732) by improving the `host:port` parsing (pick last `:` since IPv6 address might contains multiple `:` characters)
- Handle backpressure properly by switching auto read off when channel writability changes
  - change auto read of the proxy-broker connection based on the writability of the client-proxy connection
  - change auto read of the client-proxy connection based on the writability of the proxy-broker connection
- Consistently handle write errors by delegating exception handling to exceptionCaught method by using `.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)`

(cherry picked from commit a1037c7)
(cherry picked from commit 1e55685)
lhotari added a commit that referenced this pull request Jun 1, 2022
…switching to auto read mode (#14713)

Refactor Proxy code to make it easier to understand and maintain. In addition, switch to use auto read mode since the proxies connections seem to stall in some cases since the proxied connection doesn't use Netty's auto read mode and the read handling doesn't seem complete.

Currently, the proxy calls `.read()` when a message is written to the connection. There might be more messages flowing in the other direction and it could result in a blocked connection with the current solution that doesn't use Netty's auto read mode.

Currently auto read is disabled in DirectProxyHandler for the connection between the proxy and the broker:
https://github.com/apache/pulsar/blob/a26905371749798ec5288fb07a69978a36aacfaa/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/DirectProxyHandler.java#L112

- replace broker host parsing with a simple solution
- pass remote host name to ProxyBackendHandler in the constructor
- rename "targetBrokerUrl" to "brokerHostAndPort" since the "targetBrokerUrl" is really "hostname:port" string
- move HA proxy message handling to ProxyBackendHandle and extract the logic to a method
- remove the static "inboundOutboundChannelMap" which was used for log level 2
  - make it obsolete by passing the peer channel id to ParserProxyHandler
 - Enable auto read in proxy and remove `ctx.read()` / `channel.read()` calls
- prepare for IPv6 support (reported as #14732) by improving the `host:port` parsing (pick last `:` since IPv6 address might contains multiple `:` characters)
- Handle backpressure properly by switching auto read off when channel writability changes
  - change auto read of the proxy-broker connection based on the writability of the client-proxy connection
  - change auto read of the client-proxy connection based on the writability of the proxy-broker connection
- Consistently handle write errors by delegating exception handling to exceptionCaught method by using `.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)`

(cherry picked from commit a1037c7)
(cherry picked from commit 1e55685)
(cherry picked from commit 9673d6c)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/proxy cherry-picked/branch-2.8 Archived: 2.8 is end of life cherry-picked/branch-2.9 Archived: 2.9 is end of life cherry-picked/branch-2.10 doc-not-needed Your PR changes do not impact docs release/2.8.4 release/2.9.3 release/2.10.1 type/bug The PR fixed a bug or issue reported a bug type/cleanup Code or doc cleanups e.g. remove the outdated documentation or remove the code no longer in use

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants