You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by Ryan Schmitt <rs...@apache.org> on 2018/11/13 22:24:33 UTC

Timeouts

I've been looking into an issue with TLS handshake timeouts on the
async client (see
https://github.com/apache/httpcomponents-client/pull/118), and I think
that this topic might benefit from a broader audit.

Currently, there are three types of timeouts we expose through RequestConfig:

1. Connection request timeout (defined as the time to wait when
requesting a connection from the connection manager)
2. Connect timeout (defined as the time to wait until a new connection
is fully established)
3. Response timeout (defined as the time to wait until arrival of a
response from the opposite endpoint); this is basically a reboot of
the "socket timeout" value exposed in previous versions

Since all of these definitions are fairly high-level, they are tricky
to implement correctly in terms of low-level IO timeouts. For example,
implementing a connection timeout in terms of a socket timeout has
surprising implications, because establishing a TLS connection
requires multiple operations on the socket (TCP handshake, followed by
two round trips for the TLS handshake). If I specify a connection
timeout of 2.5 seconds, and each round trip to the remote host takes 2
seconds, will the connection attempt actually time out as it ought to?
(This scenario can be made almost arbitrarily complicated by adding
proxy hops to the route, HTTP auth challenge/response steps, and so
forth.)

A similar point applies to the response timeout: the definition is
somewhat ambiguous, because "the arrival of a response" can be
interpreted as (1) the initial bytes of the response, (2) the end of
the response, or (3) the next packet of the response (i.e. max wait
time per read operation, which is basically the definition of
socketTimeout). These definitions are only approximately the same in
the case of relatively short and simple responses, not long-running
streams.

Interactions are another subtlety: timeouts can interact with each
other, as well as with other client features. Is the connection
request considered part of the connection phase, or are they logically
separate? Is it meaningful for the connection request timeout to be
longer than the request timeout? If I hit the connectionTimeout, what
does the DefaultHttpRequestRetryHandler do?

Finally, there's the question of synchronous versus asynchronous IO.
Do we expect to be able to implement the exact same timeout behavior
on NIO and BIO, or will we have to make compromises somewhere?

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: Timeouts

Posted by Ryan Schmitt <rs...@pobox.com>.
Fair enough, this mainly sounds like a matter of documentation. I
still think there's some connectTimeout/socketTimeout confusion in the
synchronous client, which I'm working on fixing.

On Fri, Nov 16, 2018 at 2:50 AM Oleg Kalnichevski <ol...@apache.org> wrote:
> I personally do not see a problem here. Connect timeout is not much
> different than socket timeout. It is not an absolute value that defines
> a deadline for the operation. Like the socket timeout, which represents
> the maximum period of time between receipt of two consecutive IP
> packets, the connect timeout represents a maximum period of inactivity
> between two consecutive operations. For instance HttpClient will
> attempt to connect to all available DNS addresses for multi-home DNS
> entries which effectively makes the deadline for the connect operation
> equal n * connectTimeout (where n is the number of IP addresses for the
> DNS entry).
>
> Oleg

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: Timeouts

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Thu, 2018-11-15 at 15:23 -0800, Ryan Schmitt wrote:
> Actually, there may be *several* problems with implementing
> connection
> timeouts in terms of socket timeouts. The first problem is that the
> connection timeout may not be honored correctly (i.e. it can be
> exceeded); the second problem is that the connection timeout and the
> socket timeout proper might not actually be independently
> configurable. I was reviewing some code I have that configures a
> synchronous Apache client, and I realized that I'm calling
> `PoolingHttpClientConnectionManagerBuilder#setDefaultSocketConfig` in
> order to configure a TLS handshake timeout. There's a comment
> assuring
> me that this timeout *only* applies to connection initialization and
> not request execution, but really either behavior is surprising.
> 
> TLS handshake timeouts have been discussed previously here:
> 
> https://issues.apache.org/jira/browse/HTTPCLIENT-1478
> 
> On Thu, Nov 15, 2018 at 12:29 PM Ryan Schmitt <rs...@pobox.com>
> wrote:
> > 
> > It very well may come down to documentation for the most part,
> > although I am curious what you think about the problems associated
> > with implementing connection timeouts in terms of socket timeouts.
> 

I personally do not see a problem here. Connect timeout is not much
different than socket timeout. It is not an absolute value that defines
a deadline for the operation. Like the socket timeout, which represents
the maximum period of time between receipt of two consecutive IP
packets, the connect timeout represents a maximum period of inactivity
between two consecutive operations. For instance HttpClient will
attempt to connect to all available DNS addresses for multi-home DNS
entries which effectively makes the deadline for the connect operation
equal n * connectTimeout (where n is the number of IP addresses for the
DNS entry).

Oleg    


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: Timeouts

Posted by Ryan Schmitt <rs...@apache.org>.
Actually, there may be *several* problems with implementing connection
timeouts in terms of socket timeouts. The first problem is that the
connection timeout may not be honored correctly (i.e. it can be
exceeded); the second problem is that the connection timeout and the
socket timeout proper might not actually be independently
configurable. I was reviewing some code I have that configures a
synchronous Apache client, and I realized that I'm calling
`PoolingHttpClientConnectionManagerBuilder#setDefaultSocketConfig` in
order to configure a TLS handshake timeout. There's a comment assuring
me that this timeout *only* applies to connection initialization and
not request execution, but really either behavior is surprising.

TLS handshake timeouts have been discussed previously here:

https://issues.apache.org/jira/browse/HTTPCLIENT-1478

On Thu, Nov 15, 2018 at 12:29 PM Ryan Schmitt <rs...@pobox.com> wrote:
>
> It very well may come down to documentation for the most part,
> although I am curious what you think about the problems associated
> with implementing connection timeouts in terms of socket timeouts.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: Timeouts

Posted by Ryan Schmitt <rs...@pobox.com>.
> I am sorry I fail to see any real issue with the current implementation
> of timeouts other than lack of documentation, so I am not sure I
> understand what you are proposing.

It very well may come down to documentation for the most part,
although I am curious what you think about the problems associated
with implementing connection timeouts in terms of socket timeouts.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: Timeouts

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Tue, 2018-11-13 at 14:24 -0800, Ryan Schmitt wrote:
> I've been looking into an issue with TLS handshake timeouts on the
> async client (see
> https://github.com/apache/httpcomponents-client/pull/118), and I
> think
> that this topic might benefit from a broader audit.
> 
> Currently, there are three types of timeouts we expose through
> RequestConfig:
> 
> 1. Connection request timeout (defined as the time to wait when
> requesting a connection from the connection manager)
> 2. Connect timeout (defined as the time to wait until a new
> connection
> is fully established)
> 3. Response timeout (defined as the time to wait until arrival of a
> response from the opposite endpoint); this is basically a reboot of
> the "socket timeout" value exposed in previous versions
> 
> Since all of these definitions are fairly high-level, they are tricky
> to implement correctly in terms of low-level IO timeouts. For
> example,
> implementing a connection timeout in terms of a socket timeout has
> surprising implications, because establishing a TLS connection
> requires multiple operations on the socket (TCP handshake, followed
> by
> two round trips for the TLS handshake). If I specify a connection
> timeout of 2.5 seconds, and each round trip to the remote host takes
> 2
> seconds, will the connection attempt actually time out as it ought
> to?
> (This scenario can be made almost arbitrarily complicated by adding
> proxy hops to the route, HTTP auth challenge/response steps, and so
> forth.)
> 
> A similar point applies to the response timeout: the definition is
> somewhat ambiguous, because "the arrival of a response" can be
> interpreted as (1) the initial bytes of the response, (2) the end of
> the response, or (3) the next packet of the response (i.e. max wait
> time per read operation, which is basically the definition of
> socketTimeout). These definitions are only approximately the same in
> the case of relatively short and simple responses, not long-running
> streams.
> 
> Interactions are another subtlety: timeouts can interact with each
> other, as well as with other client features. Is the connection
> request considered part of the connection phase, or are they
> logically
> separate? Is it meaningful for the connection request timeout to be
> longer than the request timeout? If I hit the connectionTimeout, what
> does the DefaultHttpRequestRetryHandler do?
> 

Hi Ryan

I am sorry I fail to see any real issue with the current implementation
of timeouts other than lack of documentation, so I am not sure I
understand what you are proposing. 

> Finally, there's the question of synchronous versus asynchronous IO.
> Do we expect to be able to implement the exact same timeout behavior
> on NIO and BIO, or will we have to make compromises somewhere?
> 

Why should NIO and BIO be different?

Oleg


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: Timeouts

Posted by Ryan Schmitt <rs...@apache.org>.
Defaults are another good topic of discussion. I personally think that
there should be some reasonable, finite default value for every
timeout. (I also think that max conns should be unlimited by default.)
But the first order of business is deciding exactly how we want the
existing timeout parameters to behave, and where the current
implementation falls short with respect to the desired end state.

On Tue, Nov 13, 2018 at 2:50 PM Gary Gregory <ga...@gmail.com> wrote:
>
> Hi Ryan,
>
> I'm glad you've brought this up as I've often considered this and have been
> asked about it, in general, and for our apps at work.
>
> In the end, a lot of users say something like "I do not want the default
> behavior to wait forever, that looks like the app is hanging. I want some
> timeout but I do not really care that it is exactly 30 seconds, it just
> needs to tell me it's hopeless to wait longer than 30 seconds or so."
>
> OTOH, I am certain there are cases where an app wants more precise control
> and I do think it is important to know that this timeout must be less than
> another or that this one is added to that one from the user's POV...
>
> IOW, I'd love to see all of this clearly coded or at least clearly
> documented as a first step.
>
> Gary

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: Timeouts

Posted by Gary Gregory <ga...@gmail.com>.
Hi Ryan,

I'm glad you've brought this up as I've often considered this and have been
asked about it, in general, and for our apps at work.

In the end, a lot of users say something like "I do not want the default
behavior to wait forever, that looks like the app is hanging. I want some
timeout but I do not really care that it is exactly 30 seconds, it just
needs to tell me it's hopeless to wait longer than 30 seconds or so."

OTOH, I am certain there are cases where an app wants more precise control
and I do think it is important to know that this timeout must be less than
another or that this one is added to that one from the user's POV...

IOW, I'd love to see all of this clearly coded or at least clearly
documented as a first step.

Gary

On Tue, Nov 13, 2018 at 3:24 PM Ryan Schmitt <rs...@apache.org> wrote:

> I've been looking into an issue with TLS handshake timeouts on the
> async client (see
> https://github.com/apache/httpcomponents-client/pull/118), and I think
> that this topic might benefit from a broader audit.
>
> Currently, there are three types of timeouts we expose through
> RequestConfig:
>
> 1. Connection request timeout (defined as the time to wait when
> requesting a connection from the connection manager)
> 2. Connect timeout (defined as the time to wait until a new connection
> is fully established)
> 3. Response timeout (defined as the time to wait until arrival of a
> response from the opposite endpoint); this is basically a reboot of
> the "socket timeout" value exposed in previous versions
>
> Since all of these definitions are fairly high-level, they are tricky
> to implement correctly in terms of low-level IO timeouts. For example,
> implementing a connection timeout in terms of a socket timeout has
> surprising implications, because establishing a TLS connection
> requires multiple operations on the socket (TCP handshake, followed by
> two round trips for the TLS handshake). If I specify a connection
> timeout of 2.5 seconds, and each round trip to the remote host takes 2
> seconds, will the connection attempt actually time out as it ought to?
> (This scenario can be made almost arbitrarily complicated by adding
> proxy hops to the route, HTTP auth challenge/response steps, and so
> forth.)
>
> A similar point applies to the response timeout: the definition is
> somewhat ambiguous, because "the arrival of a response" can be
> interpreted as (1) the initial bytes of the response, (2) the end of
> the response, or (3) the next packet of the response (i.e. max wait
> time per read operation, which is basically the definition of
> socketTimeout). These definitions are only approximately the same in
> the case of relatively short and simple responses, not long-running
> streams.
>
> Interactions are another subtlety: timeouts can interact with each
> other, as well as with other client features. Is the connection
> request considered part of the connection phase, or are they logically
> separate? Is it meaningful for the connection request timeout to be
> longer than the request timeout? If I hit the connectionTimeout, what
> does the DefaultHttpRequestRetryHandler do?
>
> Finally, there's the question of synchronous versus asynchronous IO.
> Do we expect to be able to implement the exact same timeout behavior
> on NIO and BIO, or will we have to make compromises somewhere?
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
> For additional commands, e-mail: dev-help@hc.apache.org
>
>