Raven DB 4.1.2 hangs on streaming query in Java

2019-08-18 05:35发布

问题:

I have a jax-rs-based REST service that I run on Tomcat 8.5 on 64bit Linux, using Java 11; this service connects to a RavenDB 4.1.2 instance, also on the same Linux machine. I make use of the streaming query to return the request result. I use Postman to submit the same request, and everything works well: the results are returned, and rather quickly.

However - it only works 10 times. When I submit the same request as previously an 11th time, the results = currentSession.advanced().stream(query); line hangs and doesn't return. At first I thought I could have something to do with the StreamingOutput or OutputStreamWriter not being closed appropriately. or perhaps something do to with the Response - but as I stepped through the deployed code in Eclipse in debug mode, I noticed that execution hangs on that streaming line. (I find exactly 10 times to be a peculiarly "human choice" kind of number...)

The relevant parts of my code:

@GET
@Path("/abcntr/{ccode}/{st}/{zm}") 
@Produces(MediaType.TEXT_PLAIN)
@Consumes(MediaType.TEXT_PLAIN)
public Response retrieveInfo(@PathParam("ccode") String ccode, @PathParam("st") String st, @PathParam("zm") String zm)
{
    (...)
    StreamingOutput adminAreaStream = new StreamingOutput()
    {
        ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();

        @Override
        public void write(OutputStream output) throws IOException, WebApplicationException
        {
            try(IDocumentSession currentSession = ServiceListener.ravenDBStore.openSession())
            {
                Writer writer = new BufferedWriter(new OutputStreamWriter(output));
                (...)
                if(indexToBeQueried.startsWith("Level0"))
                {                                         
                    IDocumentQuery<AdministrativeArea> query = currentSession.query(area.class, Query.index(indexToBeQueried))
                            .whereEquals("i", ccode);
                    results = currentSession.advanced().stream(query); 
                }
                else 
                {
                    IDocumentQuery<AdministrativeArea> query = currentSession.query(area.class, Query.index(indexToBeQueried))
                            .whereEquals("i", ccode)
                            .andAlso()
                            .whereEquals("N1", sName);
                    results = currentSession.advanced().stream(query);  // THIS IS WHERE IT DOESNT COME BACK
                }
                while(results.hasNext())
                {
                    StreamResult<AdministrativeArea> adma = results.next();  
                    adma.getDocument().properties = retrievePropertiesForArea(adma.getDocument(), currentSession);
                    writer.write(ow.writeValueAsString(adma.getDocument()));
                    writer.write(",");
                }

                (...)
                currentSession.advanced().clear();
                currentSession.close();
            }
            catch (Exception e)
            {
                System.out.println("Exception: " + e.getMessage() + e.getStackTrace());
            }
        }
    };

    if(!requestIsValid)
        return Response.status(400).build();
    else
        return Response.ok(adminAreaStream).build();
}

The RavenDB error logs come up empty, as do the Tomcat error logs. The only thing that remotely resembles an error message relevant to this is something that shows up from "Gather debug info":

System.ArgumentNullException: Value cannot be null.
Parameter name: source
   at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate)
   at Raven.Server.Documents.Handlers.Debugging.QueriesDebugHandler.QueriesCacheList() in C:\Builds\RavenDB-Stable-4.1\src\Raven.Server\Documents\Handlers\Debugging\QueriesDebugHandler.cs:line 181
   at Raven.Server.ServerWide.LocalEndpointClient.InvokeAsync(RouteInformation route, Dictionary`2 parameters) in C:\Builds\RavenDB-Stable-4.1\src\Raven.Server\ServerWide\LocalEndpointClient.cs:line 61
   at Raven.Server.ServerWide.LocalEndpointClient.InvokeAndReadObjectAsync(RouteInformation route, JsonOperationContext context, Dictionary`2 parameters) in C:\Builds\RavenDB-Stable-4.1\src\Raven.Server\ServerWide\LocalEndpointClient.cs:line 91
   at Raven.Server.Documents.Handlers.Debugging.ServerWideDebugInfoPackageHandler.WriteForDatabase(ZipArchive archive, JsonOperationContext jsonOperationContext, LocalEndpointClient localEndpointClient, String databaseName, String path) in C:\Builds\RavenDB-Stable-4.1\src\Raven.Server\Documents\Handlers\Debugging\ServerWideDebugInfoPackageHandler.cs:line 311

Thank you for any kinds of investigation hints you can give me.

UPDATE: Same thing when moving the compiler and Tomcat JVM back to Java 1.8.

回答1:

It appears that it has nothing to do with Java 11 (or 1.8), but simply that it had slipped my attention to close CloseableIterator<StreamResult<AdministrativeArea>> results; After adding a simple results.close(); everything appears to work as it should. If this wasn't the solution, I'll come back and update.