org.apache.lucene.search

## Class SearcherLifetimeManager

- java.lang.Object
- - org.apache.lucene.search.SearcherLifetimeManager

- All Implemented Interfaces:
    Closeable, AutoCloseable

      public class SearcherLifetimeManager
      extends Object
      implements Closeable

  Keeps track of current plus old IndexSearchers, closing the old ones once they have timed out. Use it like this:

         SearcherLifetimeManager mgr = new SearcherLifetimeManager();

  Per search-request, if it's a "new" search request, then obtain the latest searcher you have (for example, by using `SearcherManager`), and then record this searcher:

         // Record the current searcher, and save the returend
         // token into user's search results (eg as a  hidden
         // HTML form field):
         long token = mgr.record(searcher);

  When a follow-up search arrives, for example the user clicks next page, drills down/up, etc., take the token that you saved from the previous search and:

         // If possible, obtain the same searcher as the last
         // search:
         IndexSearcher searcher = mgr.acquire(token);
         if (searcher != null) {
           // Searcher is still here
           try {
             // do searching...
           } finally {
             mgr.release(searcher);
             // Do not use searcher after this!
             searcher = null;
           }
         } else {
           // Searcher was pruned -- notify user session timed
           // out, or, pull fresh searcher again
         }

  Finally, in a separate thread, ideally the same thread that's periodically reopening your searchers, you should periodically prune old searchers:

         mgr.prune(new PruneByAge(600.0));

  NOTE: keeping many searchers around means you'll use more resources (open files, RAM) than a single searcher. However, as long as you are using `DirectoryReader.openIfChanged(DirectoryReader)`, the searchers will usually share almost all segments and the added resource usage is contained. When a large merge has completed, and you reopen, because that is a large change, the new searcher will use higher additional RAM than other searchers; but large merges don't complete very often and it's unlikely you'll hit two of them in your expiration window. Still you should budget plenty of heap in the JVM to have a good safety margin.

  WARNING: This API is experimental and might change in incompatible ways in the next release.

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `static class` | `SearcherLifetimeManager.PruneByAge` Simple pruner that drops any searcher older by more than the specified seconds, than the newest searcher.
    `static interface` | `SearcherLifetimeManager.Pruner` See `prune(org.apache.lucene.search.SearcherLifetimeManager.Pruner)`.

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `SearcherLifetimeManager()`

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `IndexSearcher` | `acquire(long version)` Retrieve a previously recorded `IndexSearcher`, if it has not yet been closed
    `void` | `close()` Close this to future searching; any searches still in process in other threads won't be affected, and they should still call `release(org.apache.lucene.search.IndexSearcher)` after they are done.
    `void` | `prune(SearcherLifetimeManager.Pruner pruner)` Calls provided `SearcherLifetimeManager.Pruner` to prune entries.
    `long` | `record(IndexSearcher searcher)` Records that you are now using this IndexSearcher.
    `void` | `release(IndexSearcher s)` Release a searcher previously obtained from `acquire(long)`.

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Constructor Detail

    - #### SearcherLifetimeManager

          public SearcherLifetimeManager()

  - ### Method Detail

    - #### record

          public long record(IndexSearcher searcher)
                      throws IOException

      Records that you are now using this IndexSearcher. Always call this when you've obtained a possibly new `IndexSearcher`, for example from `SearcherManager`. It's fine if you already passed the same searcher to this method before.

      This returns the long token that you can later pass to `acquire(long)` to retrieve the same IndexSearcher. You should record this long token in the search results sent to your user, such that if the user performs a follow-on action (clicks next page, drills down, etc.) the token is returned.

      Throws:
        `IOException`

    - #### acquire

          public IndexSearcher acquire(long version)

      Retrieve a previously recorded `IndexSearcher`, if it has not yet been closed

      NOTE: this may return null when the requested searcher has already timed out. When this happens you should notify your user that their session timed out and that they'll have to restart their search.

      If this returns a non-null result, you must match later call `release(org.apache.lucene.search.IndexSearcher)` on this searcher, best from a finally clause.

    - #### release

          public void release(IndexSearcher s)
                       throws IOException

      Release a searcher previously obtained from `acquire(long)`.

      NOTE: it's fine to call this after close.

      Throws:
        `IOException`

    - #### prune

          public void prune(SearcherLifetimeManager.Pruner pruner)
                     throws IOException

      Calls provided `SearcherLifetimeManager.Pruner` to prune entries. The entries are passed to the Pruner in sorted (newest to oldest IndexSearcher) order.

      NOTE: you must periodically call this, ideally from the same background thread that opens new searchers.

      Throws:
        `IOException`

    - #### close

          public void close()
                     throws IOException

      Close this to future searching; any searches still in process in other threads won't be affected, and they should still call `release(org.apache.lucene.search.IndexSearcher)` after they are done.

      NOTE: you must ensure no other threads are calling `record(org.apache.lucene.search.IndexSearcher)` while you call close(); otherwise it's possible not all searcher references will be freed.

      Specified by:
        `close` in interface `Closeable`
      Specified by:
        `close` in interface `AutoCloseable`
      Throws:
        `IOException`

Copyright © 2000-2022 Apache Software Foundation. All Rights Reserved.