Am using Lucene API in a .net web application. I want to use the same instance of Indexsearcher for all the requests.Hence am storing indexsearcher instance in http cache.<
Steve, see best ways of using IndexSearcher. This is a bit dated, but the principle remains: Use a single instance of IndexSearcher, guard it using the proper thread safe code (which I do not know how to do in .Net), and invalidate it once the index is updated. I believe this is what Jesse has suggested, and I second this idea.
Instead of caching indexSearcher, am now caching IndexReader. If IndexReader is already in cache, am making a check if it is up to date.Otherwise am opening it and passing that instance to indexSearcher constructor.
Does this logic/code make sense wrt optimized search query response incase multiple requests are hitting the web server for search?
Thanks for reading.
string key = MyConstants.CacheKey.IndexReader;
indexReader = MyCacheManager.Get<IndexReader>(key);
if (indexReader == null)//cache is empty.open indexreader
{
indexReader = IndexReader.Open(myIndexFolderPath);
MyCacheManager.Add(key, indexReader);
indexSearcher = new IndexSearcher(indexReader);
}
else//cache contains indexreader...check if it is up to date
{
indexSearcher = base.GetIndexSearcher(myIndexFolderPath, indexReader);
}
protected IndexSearcher GetIndexSearcher(string indexFolderPath, IndexReader indexReader)
{
IndexSearcher indexSearcher = null;
if (!indexReader.IsCurrent())//index is not up to date
{
indexReader = IndexReader.Open(indexFolderPath);
indexSearcher = new IndexSearcher(indexReader);
}
else
{
indexSearcher = new IndexSearcher(indexReader);
}
return indexSearcher;
}
My quick answer is...
You don't really need to use the same index searcher object for all request, in fact i would recommend against it. You only need to make sure there is only one thread updating the index.
If you really want one, how about a static member variable in the application that is initialized once and used by all?
The long answer is... I will try and find my code and see exactly how I handled the problem
Two things:
Both entries refer to objects in the cache being expired too soon - almost immediately in both cases. Things might also be complicated by the fact that objects in the cache are not thread safe.
If you have to have a single IndexSearcher, why not provide it to the web app as a service?
First of all it's not safe at all, it should be:
var searcher = (IndexSearcher)HttpRuntime.Cache["IndexSearcher"];
if(searcher == null)
{
searcher = new IndexSearcher(jobIndexFolderPath);
HttpRuntime.Cache["IndexSearcher"] = searcher;
}
In your code cache can expire between check and assignment
Try something like the following:
protected static IndexSearcher searcher = null;
...
if (searcher == null)
{
searcher = new IndexSearcher(jobIndexFolderPath);
}