2020-03-21

Hibernate Search - Timeout

Timeout

You can limit the time it takes for a search query to execute in two ways:

Aborting (throwing an exception) when the time limit is reached with failAfter().

Truncating the results when the time limit is reached with truncateAfter().

Currently, the two approaches are incompatible: trying to set both failAfter and truncateAfter will result in unspecified behavior.

failAfter(): Aborting the query after a given amount of time
By calling failAfter(…​) when building the query, it is possible to set a time limit for the query execution. Once the time limit is reached, Hibernate Search will stop the query execution and throw a SearchTimeoutException.

Timeouts are handled on a best-effort basis.

Depending on the resolution of the internal clock and on how often Hibernate Search is able to check that clock, it is possible that a query execution exceeds the timeout. Hibernate Search will try to minimize this excess execution time.

Triggering a failure on timeout

            try {
                SearchResult<Book> result = searchSession.search( Book.class ) 
                        .where( f -> f.match()
                                .field( "title" )
                                .matching( "robot" ) )
                        .failAfter( 500, TimeUnit.MILLISECONDS ) 
                        .fetch( 20 ); 
            }
            catch (SearchTimeoutException e) { 
                // ...
            }
Build the query as usual.
Call failAfter to set the timeout.
Fetch the results.
Catch the exception if necessary.
explain() does not honor this timeout: this method is used for debugging purposes and in particular to find out why a query is slow.

truncateAfter(): Truncating the results after a given amount of time
By calling truncateAfter(…​) when building the query, it is possible to set a time limit for the collection of search results. Once the time limit is reached, Hibernate Search will stop collecting hits and return an incomplete result.

Timeouts are handled on a best-effort basis.

Depending on the resolution of the internal clock and on how often Hibernate Search is able to check that clock, it is possible that a query execution exceeds the timeout. Hibernate Search will try to minimize this excess execution time.

Truncating the results on timeout

            SearchResult<Book> result = searchSession.search( Book.class ) 
                    .where( f -> f.match()
                            .field( "title" )
                            .matching( "robot" ) )
                    .truncateAfter( 500, TimeUnit.MILLISECONDS ) 
                    .fetch( 20 ); 

            Duration took = result.getTook(); 
            Boolean timedOut = result.isTimedOut(); 

Build the query as usual.
Call truncateAfter to set the timeout.
Fetch the results.
Optionally extract took: how much time the query took to execute.
Optionally extract timedOut: whether the query timed out.

No comments:

Post a Comment