jakarta-jcs-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Christian Kreutzfeldt <christian.kreutzfe...@gmx.de>
Subject Re: Finally, JCS updated links.
Date Fri, 02 Apr 2004 09:11:25 GMT
On Friday 02 April 2004 03:24, Travis Savo wrote:


What happened? The list seems to become alive again, great!!!

> No, but I'de love to. Can someone send me the patch?
Okay, I created patch files for those classes that I've altered.
Since someone mentioned that the list swallowed my attachments
last time I posted them, I placed them on a web server where
you can download it (http://www.students.mu-luebeck.de/~kreutzfe/jcs/)

I made some changes which are useful not only for the disk cache
but jcs as such, for example the usage of the interfaces as return
values and not their concrete implementations. BTW, I also implemented
a class CacheListenerTypes which does contain constants indicating 
which type of listener is connected to a specific cache region. 
Well, generally it would be better not to rely on constants but on the
correct implementation of the class but in case of the disk cache the
application must wait until the cache persisted all objects.

Okay, for further information about the changes I'll append the mail
which explain all the changes in detail.

Kind regards,

ics - interactive Computer Systems
Christian Kreutzfeldt
Dorfstrasse 13
23847 Stubben
t: ++49 4534 298246
f: ++49 4534 8244

> Elements seem to be placed in the EventQueue where the
> QProcessor-Thread processes them each. When the user calles
> CompositeCache#dispose() the method CacheEventQueue#destory()
> is called somewhere during the disposing process. This leads to
> an immediate interruption of the QProcessor thread. Since elements
> which have not been processed by now are abanonded and get never
> written to disk. BUT..it is not as easy as it seems since the writing
> process requires a read-write-lock. While waiting for this lock, the  
> thread is set to sleep-mode. Everything works fine until the 
> QProcessor is interrupted. The read-write-lock is acquired during the 
> execution of  the QProcessor-Thread. If that thread is interrupted the 
> retrieval of the  lock is also interrupted. That leads to a write error of 
> the last object.  This is a problem especially during the shutdown.
> Therefore the saving  process must tell the calling method that the 
> object has been successfully stored to disk. That leads to a changement 
> of the interface of AbstractDiskCache#doUpdate(). I will describe that
> later.
> Beside that there is a flag 'alive' which indicates if a specific cache
> is still alive. At the beginning of the dispose process this alive  
> flag is set
> to false in the AbstractDiskCache implementation. Unfortunately the  
> dispose
> method of the IndexedDiskCache heavily relies on a positive value of  
> alive
> during the dispose process. So, if this flag is set to false the cache  
> cannot
> be finished properly.
> AND...I accidentially figured out that there seems to be a bug in
> IndexedDiskCache#readElement. I received a ClassCastException sometime
> when I tested my modifications. I could reproduce that error but only
> accidentially. I checked what was the result of
> CacheElement object = dataFile.readObject( ded.pos ); (where the  
> Exception
> was thrown)
> and realized that sometime this method returns a PurgatoryElement
> instead of a CacheElement. I would propose a change of the method  
> interface
> from CacheElement to ICacheElement. It is always the better solution  
> to use
> the interface instead of a concrete implementation.
> Therefore I modified three things:
> 1. The alive flag is set to false _after_ the disposal of the cache and
> 2. The QProcessor can be interrupted as usual but all remaining  
> elements
>     are being processed.
> 3. Changed the method interfaces from CacheElement to ICacheElement  
> where
>     necessary
> An open question is, what if there are other caches than the  
> IndexedDiskCache.
> The IndexedDiskCache requires that all data is written to disk, but  
> some other
> implementations may not. So, the problem is, that the remaining  
> elements are
> being processed as when the QProcessor has been interrupted as if the  
> cache
> is still alive. That might lead to problems with other cache types. A
> solution would be a kind of a cache type flag which indicates what  
> kind of a
> listener receives the update information. The final processing could be
> skipped if the cache is of other type than IndexedDiskCache. I  
> implemented a
> proposal.
> Changes:
> ALIVE-Flag:
> I modified the following methods:
> 1. AbstractDiskCache#dispose():
> Removed the alive = true line from the top and placed it right after  
> the
> doDispose() statement.
> This modification ensures that the disposal process is executed at  
> least once.
> QProcessor:
> I modified the following methods:
> 1. AbstractDiskCache#doUpdate():
> I modified the interface from void doUpdate to boolean doUpdated in  
> order
> to do some post-processing when the doUpdate method has been executed  
> by
> AbstractDiskCache#MyCacheListener#handlePut(). Right now the object
> is removed from purgatory after doUpdate even if the object could not  
> be
> written due to an error. So, in order to get all objects properly to  
> disk, it
> must be ensured that the object has been stored before it can be  
> removed from
> purgatory. Therefore I changed that interface.
> The IndexedDiskCache#doUpdate now returns false if an error occurred.  
> The
> removal of the element from the purgatory depends on the return value.
> All remaining elements which could not be written to disk for any  
> reason and
> are still in the purgatory get written to disk separately in
> IndexedDiskCache#doDispose().
> The reason why this post-processing and changement of the interface is
> required, is the interruption of the QProcessor which could lead to  
> trouble
> with the ReadWriteLock class. (I described that above).
> --> the changement of the interface led to minor changes in all  
> classes which
> extend the AbstractDiskCache
> 2. IndexedDiskCache#doUpdate()
> First of all I changed the return value from void to boolean. Second  
> the
> method returns false if an exception is thrown.
> 3. IndexedDiskCache#doDispose()
> I explicitaly call cacheEventQueue#destroy() and then wait for the  
> queue to
> be finished with any post-processing. After that I do check the  
> purgatory for
> any elements that have not been written to disk yet and write them  
> away.
> 4. CacheEventQueue general:
> I changed the name of the QProcessor-Thread from t to qProcessorThread  
> used the concrete class name to reference it. Now it says
> private QProcessor qProcessorThread;
> 5. CacheEventQueue#QProcessor#run():
> The class now contains another state variable 'finished' which  
> indicates
> whether the queue has been totally processed or not.
> Beside that the run method continues to process the remaining event  
> elements
> if the listener is of type DISK_LISTENER.
> 6. CacheEvenQueue#destroy():
> The method works as before beside that it after the interruption it  
> waits for
> the QProcessor to have totally finished its work.
> ICacheListener:
> I introduced a new class (CacheListenerTypes) in package
> org.apache.jcs.utils.config. It contains a set of integer values  
> indicating
> which type a certain cache listener has. See  
> CacheEventQueue#QProcessor#run()
> how to use it.
> ICacheElement:
> As I've stated in my introduction, the IndexedDiskCache uses concrete  
> cache
> element type implementations instead of their interface as return  
> values. I
> changed that from CacheElement to ICacheElement in order to avoid some
> nasty ClassCastExceptions. I don't know how a purgatory element could  
> make
> its way into the disk cache but I found one.

To unsubscribe, e-mail: turbine-jcs-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: turbine-jcs-user-help@jakarta.apache.org

View raw message