Skip to content

Optimize connection close logic to resolve timeout delay issue - #508

Merged
ok2c merged 7 commits into
apache:masterfrom
ooeunz:feature/timeout-rst
Nov 28, 2024
Merged

Optimize connection close logic to resolve timeout delay issue#508
ok2c merged 7 commits into
apache:masterfrom
ooeunz:feature/timeout-rst

Conversation

@ooeunz

@ooeunzooeunz commented Nov 27, 2024

Copy link
Copy Markdown
Contributor

Description

  • Introduced a configuration option useRstOnTimeout in Http1Config to allow connections to be closed with an RST (Reset) signal when a timeout occurs.
  • Updated HttpRequestExecutor to respect this configuration and invoke the appropriate close mode (CloseMode.IMMEDIATE for RST or Closer.closeQuietly for FIN).
  • Maintained backward compatibility by defaulting to FIN-based connection closure.

This change improves flexibility and allows faster resource cleanup in timeout scenarios, aligning with the HTTP/1.1 recommendations for abnormal connection termination.

Problem Description

There is an issue where the connection close operation takes as long as the SocketTimeout value set in the SocketConfig after a Socket timeout occurs. This behavior arises because the NioSocketImpl performs an additional poll for the duration of the SocketTimeout during the close operation. Consequently, HTTP requests may experience delays of up to twice the configured SocketTimeout value.

Proposed Solution

This Pull Request introduces the useRstOnTimeout configuration option to mitigate this issue by enabling connections to be closed using an RST signal instead of a FIN-based closure.

  • Key benefits:
    • Avoids unnecessary delays during connection closure.
    • Ensures efficient resource cleanup.
    • Maintains backward compatibility by defaulting to FIN-based closure.

The following image shows the test results with the socket timeout value set to 5 seconds
img-1

img-2

Example Workflow Before Fix

  1. Socket timeout occurs:
    The socket reaches the timeout value specified in the SocketTimeout configuration.
  2. Connection close:
    During the close operation, the NioSocketImpl performs an additional poll for the same timeout duration.
  3. Total wait time:
    HTTP requests may end up waiting for up to twice the configured SocketTimeout value.

Resolves: HTTPCLIENT-2324

- Introduced a configuration option `useRstOnTimeout` in `Http1Config`
to allow connections to be closed with an RST (Reset) signal when
a timeout occurs.
- Updated `HttpRequestExecutor` to respect this configuration and
invoke the appropriate close mode (`CloseMode.IMMEDIATE` for RST
or `Closer.closeQuietly` for FIN).
- Maintained backward compatibility by defaulting to FIN-based
connection closure.
This change improves flexibility and allows faster resource
cleanup in timeout scenarios, aligning with the HTTP/1.1
recommendations for abnormal connection termination.
Resolves: HTTPCLIENT-2324

@ok2cok2c 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.

return initialWindowSize;
}

public boolean getUseRstOnTimeout() {

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.

@ooeunz Please add @since 5.4 tag

return this;
}

public Builder setUserRstOnTimeout(final boolean userRstOnTimeout) {

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.

@ooeunz Please add @since 5.4 tag

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Added. Thanks.

@garydgregorygarydgregory 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.

Hello @ooeunz

See my comments.

Is it possible to write a test that shows the new code does anything?

}

/**
* @since 5.4

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.

I think you need a real Javadoc description that explains what this toggle does.


} catch (final HttpException | IOException | RuntimeException ex) {
Closer.closeQuietly(conn);
if (http1Config.getUseRstOnTimeout()) {

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.

Is there a use case for keeping the old behavior?

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.

@garydgregory Graceful shutdown of TLS connections would be one. One can drop a TLS connection without a close-notify handshake but it is generally considered rude.

@ooeunz Why do not we always use IMMEDIATE close for plain (non TLS) conections by default? Would that make the new config flag redundant?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

To maintain backward compatibility, the existing behavior has been preserved.

However, if it is determined that there are no issues with backward compatibility, I would like to make immediate close the default behavior.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I think that a socket timeout indicates that the server is not functioning properly, so setting immediate close as the default behavior should not cause any issues.

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.

TY @ok2c for the explanation. I think details like this should be in the Javadoc for the getter-setter pair.

@ok2c

ok2c commented Nov 27, 2024

Copy link
Copy Markdown
Member

@ooeunz Almost there. Please fix the style check violations and update the title of PR and will merge the change-set.

@ooeunzooeunz changed the title Introduce useRstOnTimeout to address extended close times after SocketTimeoutOptimize connection close logic to resolve timeout delay issueNov 27, 2024
@ooeunz

Copy link
Copy Markdown
ContributorAuthor

@ok2c@garydgregory I’ve completed refining the code style. It was such an enjoyable experience to collaborate and build the code together! 😊

@ok2c
ok2c merged commit 8ee6483 into apache:masterNov 28, 2024
@ok2c

ok2c commented Nov 28, 2024

Copy link
Copy Markdown
Member

@ooeunz Cherry-picked to 5.3.x

Sign up for freeto 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.

3 participants

@ooeunz@ok2c@garydgregory