IndexReader locks files
See original GitHub issueI’ve got an odd file lock problem after updating from v3 to v4. I’m not sure if this is just poor design choices or an actual issue but the behavior is definitely different now.
Here is a simple scenario that seems like doesn’t work how I think it should.
- Create an application that creates an IndexWriter using a path, add a bunch of documents, and commit it. You should get some index files on disk at that path.
- Create a IIS website that opens an IndexReader using that same path and IndexSearcher and then execute a search for one of those docs.
- Go to disk and attempt to delete all the files lucene.net created in the index path.
Expected behavior: the files are deleted Actual behavior: some files are locked by the w3wp.exe process in IIS that used the reader and cannot be deleted.
Negative side effect: if the writer runs again it can also run into this issue where it can’t update some of those files. Workaround: dispose of the reader every time you search. Not necessarily a bad thing, but uses more memory and is slower.
Why is the reader locking any files? The reader is specifically a static variable created one time and disposed on a timed basis for efficiency. My understanding is the reader is thread safe and since we don’t care about real-time updates, this is more efficient than opening a new reader every time we do a search.
Posting the relevant code:
private static DirectoryReader _reader;
private static indexPath = @"C:\index\";
public void Search(){
if(_reader==null){
_reader = DirectoryReader.Open(FSDirectory.Open(new DirectoryInfo(indexPath)), 8);
}
BooleanQuery mainQuery;
Sort sort;
IndexSearcher searcher = new IndexSearcher(_reader);
int numDocs = _reader.NumDocs;
var collector = TopFieldCollector.Create(sort, numDocs, true, true, true, false);
searcher.Search(mainQuery, collector);
}
public void Index(){
IndexWriterConfig indexConfig = new IndexWriterConfig(LuceneVersion.LUCENE_48, new StandardAnalyzer(LuceneVersion.LUCENE_48));
var writer = new IndexWriter(FSDirectory.Open(indexPath), indexConfig)
var luceneDocument = new Lucene.Net.Documents.Document();
luceneDocument.Add(new TextField("DocumentId", "Unique ID", Field.Store.YES));
writer.UpdateDocument(new Term("DocumentId", "Unique ID Here"), luceneDocument);
writer.Commit();
}
Issue Analytics
- State:
- Created 2 years ago
- Comments:7 (5 by maintainers)
For now, I went with Approach 1 - Point in time Reader. I added a loop on the delete all, just incase something is locked for a backup, waiting a few seconds in-between loops. I don’t consider this the ideal solution, but it was the easiest to implement quickly. I’ll be testing it more to see how it works, but the first look seems ok. I’ll explore Approach 2 more later when I have time. I also like the idea of moving all searching to the windows service and out of IIS. IIS has so many other problems it seems to make sense to run anything I can in the service.
Closing as this question appears to be answered.