4 Replies Latest reply on Jul 17, 2015 5:30 AM by Wessel Nieboer

    Query.cancel() and NIOFSDirectory

    Wessel Nieboer Novice

      Hi all,

       

      We are currently cancelling queries with the following code if they take too long:

       

       

      private class SearchTask implements Callable<QueryResult> {

         private Query query;

       

         @Override
         public QueryResult call() throws Exception {

         return query.execute();

        }

       

         protected SearchTask( Query query ) {

         this.query = query;

        }

      }

       

       

       

      FutureTask<QueryResult> result = new FutureTask<>( new SearchTask( query ) );

      executor.execute( result );

       

      NodeIterator it;

      try {

         // Wait specified amount of time for search to complete.
         it = result.get( searchTimeout, TimeUnit.SECONDS ).getNodes();

      } catch ( InterruptedException | ExecutionException e ) {

         throw new ContentManagerException( e );

      } catch ( TimeoutException e ) {

         logger.warn( "Query timed out after {} seconds!", searchTimeout );

        result.cancel( true );

        ( (org.modeshape.jcr.api.query.Query) query ).cancel();

         throw new SearchTimeoutException(xxx );

      }

       

       

      But since we are using the NIOFSDirectory (3.x branch hibernate search etc) this is causing issues for us, see the following:

       

      java.nio.channels.ClosedChannelException

      at sun.nio.ch.FileChannelImpl.ensureOpen(FileChannelImpl.java:109) ~[?:1.8.0_25]

      at sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:688) ~[?:1.8.0_25]

      at org.apache.lucene.store.NIOFSDirectory$NIOFSIndexInput.readInternal(NIOFSDirectory.java:162) ~[lucene-core-3.6.2-redhat-4.jar!/:3.6.2-redhat-4]

       

      {quote}

      NOTE: Accessing this class either directly or indirectly from a thread while it's interrupted can close the underlying file descriptor immediately if at the same time the thread is blocked on IO. The file descriptor will remain closed and subsequent access to NIOFSDirectory will throw a ClosedChannelException. If your application uses either Thread.interrupt() or Future.cancel(boolean) you should use SimpleFSDirectory in favor ofNIOFSDirectory.

      {quote}

      NIOFSDirectory (Lucene 3.5.0 API)

       

       

      Will leaving out the result.cancel ( true ); make sure the Query is correctly cancelled? I am not sure how the underlying query system works. It seems to only mark a query as cancelled so I would presume it to be cancelled correctly. And if so: would this mean the query is still processing, and we are just not waiting for it?

       

      Thanks in advance!