Send `OPTIONS *` request when connection is idle in HTTP/1
See original GitHub issueWhen an intermediary load balancer proxies a request to an endpoint, an Armeria client that sends a request via the load balancer will sometimes get a ClosedSessionException due to a race condition like the following:
- The LB thinks the connection A is idle and decides to close the connection.
- Armeria client thinks it can reuse the connection A and sends the request to the connection A.
- The LB closes the connection.
- Armeria client gets a
ClosedSessionException.
To fix the problem, a user can increase the idle timeout of the load balancer, but we could also send something similar to HTTP/2 PING frames, such as OPTIONS * HTTP/1.1, on an idle HTTP/1 connection with no active streams.
We will be able to reuse @sivaalli’s work.
I think we are going to have to make the following two changes:
- Remove the
sendPingsOnNoActiveStreamsflag and send pings even if there are no active streams, so that an idle HTTP/2 connections are protected from the same problem.- Instead, allow a user to specify the interval between pings, which is expected to be less than the idle timeout.
- As a result, we are going to have to keep track of two idle states, by using two
IdleStateHandleror by forkingIdleStateHandlerfor efficiency.
- When there are no requests in progress in an HTTP/1 connection, send a
OPTIONS * HTTP/1.1request as a ping to keep the connection alive.- The connection should still be closed when a user does not send requests until idle timeout occurs.
The first change is not necessary part of this issue, but I guess it will be much easier to implement the second change with the first one.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:4
- Comments:6
Top Results From Across the Web
OPTIONS - HTTP - MDN Web Docs - Mozilla
In CORS, a preflight request is sent with the OPTIONS method so that the server can respond if it is acceptable to send...
Read more >HTTP/1.1: Connections
For example, a client might have started to send a new request at the same time that the server has decided to close...
Read more >Why is an OPTIONS request sent and can I disable it?
Options request is a preflight request when you send (post) any data to another domain. It's a browser security issue. But we can...
Read more >What is HTTP Keep Alive | Benefits of Connection ... - Imperva
By default, HTTP connections close after each request. When someone visits your site, their browser needs to create new connections to request each...
Read more >HTTP Keep-Alive, Pipelining, Multiplexing and Connection ...
The HTTP 1.0 protocol does not support persistent connections by default. In order to do so, the client has to send a Connection...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

That would be a different issue. I’m actually investigating it as well internally. 😄
Hmm - this doesn’t sound right to me. If the connection has already gone away, future requests should try a new connection instead of being failed right away by this exception. I think that’s the point of goaway. Is this something we need to fix in our client?
Ah I think right now we only ping if idle timeout is defined but this means flag-wise ping and idle timeout are completely decoupled? That seems nice.
Not sure how much it scatters - HTTP/2 and 1 are so different that this handling of idleness seems like it should be special cased for each so it’s optimal. For example, I still think the existence of goaway is a huge game changer between the two. If this hypothesis that they are very different is true is correct anyways, I’m feeling that the connection pool would be a good layer for HTTP/1. It does make me wonder perhaps it’s the pool itself that should be special cased for each protocol.