Even if you could tell a reader is closed, you'd wind up with unmaintainable code. I envision you have a bunch of places where you'd do something like
if (reader.isClosed()) { reader = create a new reader. } But practically, you'd be opening a new reader someplace, closing it someplace else, opening it in another place...... This just leads to maintenance nightmares. For instance, how could you determine what the state of a particular reader was when trying to figure out why your searches didn't work if you don't have a clue where/when it was opened? Perhaps the easiest thing to do if you can't restructure your code as Michael suggested is just employ a singleton pattern to give you complete control over when/where a reader is opened..... Best Erick On Dec 12, 2007 5:36 AM, Michael McCandless <[EMAIL PROTECTED]> wrote: > > Ruslan Sivak wrote: > > > Michael McCandless wrote: > >> > >> Ruslan Sivak wrote: > >> > >>> I have an index of about 10mb. Since it's so small, I would like > >>> to keep it loaded in memory, and reload it about every minute or > >>> so, assuming that it has changed on disk. I have the following > >>> code, which works, except it doesn't reload the changes. > >>> protected String indexName; > >>> protected IndexReader reader; > >>> private long lastCheck=0; > >>> ... > >>> protected IndexReader getReader() throws CorruptIndexException, > >>> IOException > >>> { > >>> if (reader==null || System.currentTimeMillis() > lastCheck > >>> +60000) > >>> { > >>> lastCheck=System.currentTimeMillis(); > >>> if (reader==null || !reader.isCurrent()) > >>> { > >>> if (reader!=null) > >>> reader.close(); > >>> Directory dir = new RAMDirectory > >>> (indexName); > >>> reader = IndexReader.open(dir); > >>> searcher = new IndexSearcher(reader); > >>> } > >>> } > >>> return reader; > >>> } > >>> > >>> > >>> Apparently reader.isCurrent() won't tell you if the underlying > >>> FSDirectory has changed. > >> > >> That's right: your reader is only searching the RAMDirectory; it > >> has no idea that your RAMDirectory was copied from an FSDirectory > >> that has now changed. (That ctor for RAMDirectory makes a full > >> copy of what's currently in the FSDirectory and thereafter > >> maintains no link to that FSDirectory). > >> > >>> I also had the following code before: > >>> instead of > >>> if (reader==null || !reader.isCurrent()) > >>> I had > >>> if (reader==null || reader.getVersion() != > >>> IndexReader.getCurrentVersion(indexName)) > >> > >> That 2nd line seems like it should have worked. What version of > >> Lucene are you using? Are you really sure it's not showing the > >> changes? Can you print the two versions? Every commit to the > >> index (by IndexWriter) should increment that version number. > >> > > The 2nd line was working fine, however I was getting errors in > > other places saying that the indexReader is closed. > > Can you restructure your code, such that you open a new reader > without first closing the old one, and then only once the open is > complete, you swap the new reader in as "reader", wait for threads to > finish using the old reader, then call close on the old one? > > >>> I was getting a bunch of this indexreader is closed errors, and > >>> I'm not sure why there's no method like reader.isClosed(). > >> > >> That's spooky: can you explain why you're accidentally using a > >> closed reader? Your code above seems to replace reader after > >> closing it. Are there other threads that are using the reader > >> while you are doing this re-opening? > >> > > There could be other threads using this, and there are other places > > in the code that open and close readers. My main problem I guess > > is that I can't tell when a reader is closed. Is there some method > > I can use? I basically want to do something like this. > > if (reader==null || reader.isClosed || reader.getVersion() != > > IndexReader.getCurrentVersion(indexName)) > > There is currently no way to ask a reader if it's closed. I suppose > you could do something like: > > try { > version = reader.getVersion(); > isClosed = false; > } catch (AlreadyClosedException e) { > isClosed = true; > } > > However this is somewhat bad form. It's better to restructure your > code such that it's not possible to accidentally use a reader you had > closed. > > > Is reader threadsafe? Should each invocation open it's own reader? > > Reader is definitely thread safe, so you should share 1 reader across > all threads. You just need to take care in your app to not close a > reader if other threads are still using it or will continue using it. > > Mike > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > >