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

Josh Elser commented on CALCITE-1315:
-------------------------------------

bq. I don't know the semantics of NoHttpResponseException. Is it possible for a 
server to repeatedly return NoHttpResponseException? If so, should you limit 
the number of retries, to avoid a loop?

Not sure if it's not re-used elsewhere (don't have enough experience with HC to 
be confident that they wouldnt' do something screwy), but, under normal 
circumstances, we shouldn't ever get into a situation where we can connect to a 
server, send a request, and get no bytes back from that server (if it's 
dead/dying, it should stop accepting the connection before we send our request).

That said, I'm not a huge fan of our existing logic inside of the 
AvaticaHttpClient impls for the reason you point out. We have very little 
insight into retries happening too (often because logging is minimized because 
we're in the context of sqlline or similar). Consolidating retry logic and 
making sure we have appropriate options to control those client-side retries as 
well as options exposed via the JDBC url would be a very good thing, but I need 
to put some more thought into the knobs that are actually necessary (to avoid 
death-by-configuratin).

Let me file another issue to look at this for 1.9.0.

> Automatically retry request when a server fails to deliver an HTTP response
> ---------------------------------------------------------------------------
>
>                 Key: CALCITE-1315
>                 URL: https://issues.apache.org/jira/browse/CALCITE-1315
>             Project: Calcite
>          Issue Type: Bug
>          Components: avatica
>            Reporter: Josh Elser
>            Assignee: Josh Elser
>             Fix For: avatica-1.9.0
>
>
> I've been running my load-balancer test using HAProxy between an Avatica 
> client and multiple avatica servers. With the help of [~speleato], we've 
> noticed that we're still seeing some intermittent failures in the client when 
> we take down a backend server.
> The client reports a NoHttpResponseException:
> {noformat}
> java.lang.RuntimeException: org.apache.http.NoHttpResponseException: 
> localhost:8888 failed to respond
>       at 
> org.apache.calcite.avatica.remote.AvaticaCommonsHttpClientImpl.send(AvaticaCommonsHttpClientImpl.java:149)
>       at 
> org.apache.calcite.avatica.remote.RemoteProtobufService._apply(RemoteProtobufService.java:44)
>       at 
> org.apache.calcite.avatica.remote.ProtobufService.apply(ProtobufService.java:69)
>       at 
> org.apache.calcite.avatica.remote.RemoteMeta$14.call(RemoteMeta.java:307)
>       at 
> org.apache.calcite.avatica.remote.RemoteMeta$14.call(RemoteMeta.java:305)
>       at 
> org.apache.calcite.avatica.AvaticaConnection.invokeWithRetries(AvaticaConnection.java:715)
>       at 
> org.apache.calcite.avatica.remote.RemoteMeta.fetch(RemoteMeta.java:304)
>       at 
> org.apache.calcite.avatica.MetaImpl$FetchIterator.moveNext(MetaImpl.java:908)
>       at 
> org.apache.calcite.avatica.MetaImpl$FetchIterator.next(MetaImpl.java:893)
>       at 
> org.apache.calcite.avatica.util.IteratorCursor.next(IteratorCursor.java:46)
>       at 
> org.apache.calcite.avatica.AvaticaResultSet.next(AvaticaResultSet.java:218)
>       at sqlline.BufferedRows.<init>(BufferedRows.java:37)
>       at sqlline.SqlLine.print(SqlLine.java:1649)
>       at sqlline.Commands.execute(Commands.java:833)
>       at sqlline.Commands.sql(Commands.java:732)
>       at sqlline.SqlLine.dispatch(SqlLine.java:807)
>       at sqlline.SqlLine.runCommands(SqlLine.java:1710)
>       at sqlline.Commands.run(Commands.java:1285)
>       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>       at 
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>       at 
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>       at java.lang.reflect.Method.invoke(Method.java:606)
>       at 
> sqlline.ReflectiveCommandHandler.execute(ReflectiveCommandHandler.java:36)
>       at sqlline.SqlLine.dispatch(SqlLine.java:803)
>       at sqlline.SqlLine.initArgs(SqlLine.java:613)
>       at sqlline.SqlLine.begin(SqlLine.java:656)
>       at sqlline.SqlLine.start(SqlLine.java:398)
>       at sqlline.SqlLine.main(SqlLine.java:292)
>       at 
> org.apache.phoenix.queryserver.client.SqllineWrapper.main(SqllineWrapper.java:83)
> Caused by: org.apache.http.NoHttpResponseException: localhost:8888 failed to 
> respond
>       at 
> org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:143)
>       at 
> org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57)
>       at 
> org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:261)
>       at 
> org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:165)
>       at 
> org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:167)
>       at 
> org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:272)
>       at 
> org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:124)
>       at 
> org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271)
>       at 
> org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
>       at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
>       at 
> org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
>       at 
> org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
>       at 
> org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
>       at 
> org.apache.calcite.avatica.remote.AvaticaCommonsHttpClientImpl.execute(AvaticaCommonsHttpClientImpl.java:157)
>       at 
> org.apache.calcite.avatica.remote.AvaticaCommonsHttpClientImpl.send(AvaticaCommonsHttpClientImpl.java:134)
>       ... 28 more
> {noformat}
> I'm pretty sure what's happening (and what I can't see as something which we 
> can change in the loadbalancer itself), is that a client submits a request to 
> the LB which is then sent to the backend server, the backend server starts 
> processing that request, but fails to ever respond. Instead of the LB sending 
> back an HTTP/503 (as we've seen it do before), the client just gets a 
> terminated connection while waiting for the response. I'm not surprised that 
> HAProxy does not automatically retry this for us.
> So, the Avatica client can just retry this instead like we do on HTTP/503's 
> already.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to