lucenenet-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Allan, Brad (Bracknell)" <Brad.Al...@Fiserv.com>
Subject RE: IndexReader disposal causing unexpected 'AlreadyClosedException'
Date Mon, 24 Mar 2014 16:25:33 GMT
Thanks Paul for responding.
The background timer is not an option for the application.

The 'cache' is only administering a single index reader for each index in my system, and the
cache does perform a reopen before returning the reader, so I am using a technique similar
to what you are describing.

It seems to me that I can call IncRef() and DecRef(). For the latter I'll have to add something
to the cache that allows 'getters' to let the cache know they are done.

-----Original Message-----
From: Paul Irwin [mailto:pirwin@feature23.com]
Sent: 24 March 2014 16:07
To: user@lucenenet.apache.org
Cc: lucene-net-user@lucene.apache.org
Subject: Re: IndexReader disposal causing unexpected 'AlreadyClosedException'

I'd recommend trying to keep the IndexReader instance as a singleton static variable. It's
safe to use across multiple threads, so there's no benefit to disposing and creating new instances.
Just call .Reopen() on it when the data changes.

What's happening here is the "reader" variable is being returned from the first call to the
method, then on the second call, you're getting the same instance back from cache and then
calling dispose on it, while the "reader1" variable still has a reference to that instance,
so when you do anything on "reader1" it's already disposed. So yeah, I would recommend keeping
an instance open singleton, never calling Dispose on it, and calling Reopen when needed.

If you need to naively call Reopen periodically because you don't know when the index changes,
you could do that on a background timer tick if you can accept slightly stale data.

Paul


On Mon, Mar 24, 2014 at 11:55 AM, Allan, Brad (Bracknell) < Brad.Allan@fiserv.com> wrote:

> I've create some pseudo code to try and describe what I'm seeing. This
> 'problem' can also be replicated without multiple threads (sessions as
> I describe them below) if the order of operations is as described below.
>
> How am I misunderstanding the Lucene docs (around Reopen() method)?
> I have looked into the source code and the Dispose does appear to not
> want to close the reader if there are existing refs. What do I need to
> do in my code to ensure the following scenario does not occur?
>
> A solution I'm mulling over is to keep an additional reference count
> for the readers I dish out from 'MyCache' and only Dispose the reader
> when MyCache knows there are no existing refs to the 'old' reader.
>
> Wise words appreciated. Thanks.
>
> // Session 1
> var reader1 = GetIndexReaderFromMyCache("MyTestIndex");
>
> // Session 2
> ....some changes are made to 'MyTestIndex'.....
>
> // Session 3
> var reader3 = GetIndexReaderFromMyCache("MyTestIndex");
>
> // Session 1
> ....perform a search with reader1....
> BOOM! get 'AlreadyClosedException'
>
> Where:
> -----------
> IndexReader GetIndexReaderFromMyCache(string indexName) {
>      lock(lockObject) {
>            IndexReader reader = MyCache.Get(indexName);
>            IndexReader newReader = reader.Reopen();
>            if (newReader != reader) {
>                 reader.Dispose();
>            }
>            reader = newReader;
>            MyCache.Update(indexName, reader);
>            return reader;
>      }
> }
>
>
> ________________________________
>
> CheckFree Solutions Limited (trading as Fiserv) Registered Office:
> Eversheds House, 70 Great Bridgewater Street, Manchester, M15 ES
> Registered in England: No. 2694333
>



--

Paul Irwin
Lead Software Engineer
feature[23]

Email: pirwin@feature23.com
Cell: 863-698-9294

________________________________

CheckFree Solutions Limited (trading as Fiserv)
Registered Office: Eversheds House, 70 Great Bridgewater Street, Manchester, M15 ES
Registered in England: No. 2694333

Mime
View raw message