[ 
https://issues.apache.org/jira/browse/HTTPCORE-377?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13976920#comment-13976920
 ] 

Dmitry Potapov commented on HTTPCORE-377:
-----------------------------------------

Yes, I want configurable linger timeout for incoming connections and RST for 
outgoing connections.

Here the full description of my case:
I have two applications, let they be Proxy and Backend. They both are 
synchronous HTTP servers built on top of HttpCore (no NIO).
Proxy also has HttpClient and for each incoming request it sends new request to 
Backend.
Backend accepts request, read some data from disk and reply with this data 
block. Proxy will process this data and reply with some digest.
Both Proxy and Backend on reply set 'Keep-Alive:' header.
Ping from Proxy to Backend is about 5-7 ms.

What happens when request comes to Proxy with "Connection: close" header?
After processing request Proxy will write reply to socket and close it. Since 
we want client to read reply completely we set SO_LINGER on server sockets to 
couple of seconds. This is not our problem if two seconds is not enough for 
client, we need to clean up this socket for new requests.
That's why we are using non-zero linger for servers. For non-NIO servers it can 
be set directly, but for DefaultListeningIOReactor the best place to set linger 
is the AbstractMultiworkerIOReactor#prepareSocket(Socket).

What happens when Backend receives heavy request which slowdowns its request 
processing for a while?
Assume we have some constant load to Proxy. Some number of connections will be 
allocated in connection manager (let say, there is 100 connections), and they 
will be used for all request to Backend. When heavy request will arrive to 
Backend, current request won't be able to complete in time, so new connections 
will be allocated from pool in order to serve new requests (let say there will 
be 20 new connections allocated). When heavy request will be processed, 
everything will go to normal, and only 100 connections will be required for 
operations. 20 allocated connections will expire and will be closed. The 
problem here is that ping to Backend is 5-7 ms, so, when connection manager 
call Socket#close(), Proxy will send FIN to Backend and will wait for FIN,ACK. 
This will take 5 ms, all this time all other connections request will be 
blocked. So, no new request will be processed in this 5 ms, so, new connections 
will be requested from pool. This will cause new connections expires and on and 
on. As the result overall system rps will fall down.
That's why we don't want to wait for FIN from Backend, so we want zero linger.

> Allow to enable SO_LINGER option with zero timeout
> --------------------------------------------------
>
>                 Key: HTTPCORE-377
>                 URL: https://issues.apache.org/jira/browse/HTTPCORE-377
>             Project: HttpComponents HttpCore
>          Issue Type: Improvement
>          Components: HttpCore, HttpCore NIO
>    Affects Versions: 4.3.2
>            Reporter: Dmitry Potapov
>            Priority: Minor
>         Attachments: httpcore-enable-linger.patch
>
>
> According to 
> http://docs.oracle.com/javase/8/docs/api/java/net/StandardSocketOptions.html#SO_LINGER
>  linger option is disabled by default. Currently if SocketConfig.soLinger is 
> set to zero (default value is -1), then Socket.setSoLinger(false, 0) will be 
> called, so linger will be disabled, which is undesirable. My suggestion is 
> interpret zero soLinger value as Socket.setSoLinger(true, 0).
> I understand that this change will break backward compatibility of config 
> interpretation, but can we have this in 4.4?



--
This message was sent by Atlassian JIRA
(v6.2#6252)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to