HTTPClient is not running out of connections? It is known to hang in such cases.
On Mon, Jul 5, 2021 at 2:58 PM james anderson <ja...@dydra.com> wrote: > > good afternoon; > > > On 2021-07-05, at 12:36:20, Andy Seaborne <a...@apache.org> wrote: > > > > > > > > On 05/07/2021 10:01, Ivan Lagunov wrote: > >> Hello, > >> We’re facing an issue with Jena reading n-triples stream over HTTP. In > >> fact, our application hangs entirely while executing this piece of code: > >> Model sub = ModelFactory.createDefaultModel(); > >> TypedInputStream stream = HttpOp.execHttpGet(requestURL, > >> WebContent.contentTypeNTriples, createHttpClient(auth), null) > >> // The following part sometimes hangs: > >> RDFParser.create() > >> .source(stream) > >> .lang(Lang.NTRIPLES) > >> .errorHandler(ErrorHandlerFactory.errorHandlerStrict) > >> .parse(sub.getGraph()); > >> // This point is not reached > > > > >> The issue is not persistent, moreover it happens infrequently. > > > > Then it looks like the data has stopped arriving but the connection is > > still open. (or the system has gone in GC overload due to heap pressure.) > > > > Is intermittent on the same data? Or is the data changing? because maybe > > the data can't be written properly and the sender stops sending, though I'd > > expect the sender to close the connection (it's now in an unknown state and > > can't be reused). > > > >> When it occurs, the RDF store server (we use Dydra for that) logs a > >> successful HTTP 200 response for our call (truncated for readability): > >> HTTP/1.1" 200 3072/55397664 10.676/10.828 "application/n-triples" "-" "-" > >> "Apache-Jena-ARQ/3.17.0" "127.0.0.1:8104" > > the situation involves an nginx proxy and an upstream sparql processor. > > > > > What do the fields mean? > > the line is an excerpt from an entry from the nginx request log. that line > contains: > > protocol code requestLength/responseLength > upstreamElapsedTime/clientElapsedTIme acceptType - - clientAgemt > upstreamPort > > > > > Is that 3072 bytes sent (so far) of 55397664? > > > > If so, is Content-Length set (and then chunk encoding isn't needed). > > likely not, as the response is (i believe) that from a sparql request, which > is emitted as it is generated. > > > > > Unfortunately, in HTTP, 200 really means "I started to send stuff", not "I > > completed sending stuff". There is no way in HTTP 1/1 to signal an error > > after starting the response. > > that is true, but there are indications in other logs which imply that the > sparql processor believes the response to have been completely sent to nginx. > there are several reasons to believe this. > the times and the 200 response code in the nginx log indicate completion. > otherwise, it would either indicate that it timed out, or would include a 499 > code, to the effect that the client closed the connection before the response > was sent. > neither is the case. > in addition, the elapsed time is well below that for which nginx would time > out an upstream connection. > > > > > The HttpClient - how is it configured? > > > >> So it looks like the RDF store successfully executes the SPARQL query, > >> responds with HTTP 200 and starts transferring the data with the chunked > >> encoding. Then something goes wrong when Jena processes the input stream. > >> I expect there might be some timeout behind the scenes while Jena reads > >> the stream > > > > Does any data reach the graph? > > > > There is no timeout at the client end - otherwise you would get an > > exception. The parser is reading the input stream from Apache HttpClient. > > If it hangs, it's because the data has stopped arriving but the connection > > is still open. > > > > You could try replacing .parse(graph) with parse(StreamRDF) and plug in a > > logging StreamRDF so you can see the progress, either sending on data to > > the graph or for investigation, merely logging. > > > > In HTTP 1.1, a streamed response requires chunk encoding only when the > > Content-Length isn't given. > > i believe, the content length is not given. > > > > > > > > , and it causes it to wait indefinitely. At the same time > > ErrorHandlerFactory.errorHandlerStrict does not help at all – no errors are > > logged. > >> Is there a way to configure the timeout behavior for the underlying Jena > >> logic of processing HTTP stream? Ideally we want to abort the request if > >> it times out and then retry it a few times until it succeeds. > > > > The HttpClient determines the transfer. > > > > Andy > > > > FYI: RDFConnectionRemote is an abstraction to make this a little easier. No > > need to go to the low-level HttpOp. > > > > > > FYI: Jena 4.mumble.0 is likely to change to using jena.net.http as the HTTP > > code. There has to be some change anyway to get HTTP/2 (Apache HttpClient > > v5+, not v4, has HTTP/2 support). > > > > This will include a new Graph Store Protocol client. > > > >> Met vriendelijke groet, with kind regards, > >> Ivan Lagunov > >> Technical Lead / Software Architect > >> Skype: lagivan > >> Semaku B.V. > >> Torenallee 20 (SFJ3D) • 5617 BC Eindhoven • www.semaku.com >