You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Jon Evans <jo...@misgl.com> on 2004/12/02 13:13:19 UTC

EHDefaultStore

Hi,

I needed a cache for part of my webapp.  Basically I can look up lists 
of things, based on a number of parameters.  I put all the parameters 
into a Serializable class which becomes the key.  If it isn't in the 
cache then I create a new object using a stored procedure and add it to 
the cache.  The stored procedure takes about 500ms, hence the need for 
the cache.

I had to create my own "version" of EHDefaultStore, specific to my app, 
because I didn't want an eternal cache.  I expire items after 5 minutes 
so that a db hit is forced (in case the data has been updated).  
Although EHDefaultStore takes many config parameters, it doesn't have 
eternal, timeToLive or timeToIdle, and is hard coded to always create 
an eternal cache.

My questions:

1) Any reason why those parameters can't be added?  Then I could have 
just configured my own instance in cocoon.xconf with a different role 
name to the default.

2) EHDefaultStore configures a CacheManager from an xml file, but then 
creates the Cache object itself using the long Cache() constructor.
 From my understanding of the EHCache docs, the xml file is used to set 
the defaults for if a Cache object is created by the CacheManager 
itself, which isn't being done in EHDefaultStore.
We might just as well use

CacheManager cacheManager = CacheManager.create(); // or getInstance()

even if the values in ehcache.xml are changed, it will make no 
difference because each Cache is programatically created using specific 
values for each property.  So we don't need it.

3) a CacheManager can manage more than one Cache, yet we create one per 
instance of EHDefaultStore.
OK, at the moment there is only one instance of EHDefaultStore (I 
think?), but if it's made more generic (see 1) then there could be 
more.  We could have a static CacheManager shared between them all.
This does however mean that we'd need an instance count so that the 
last instance could call cacheManager.shutdown() (and the first client 
would call create()).  But then we already do have an instance count 
which is used in EHDefaultStore to generate a new name each time the 
constructor is called.

Shall I submit a patch adding any of the above?

Jon


Re: EHDefaultStore

Posted by Unico Hommes <un...@hippo.nl>.
On 2-dec-04, at 14:35, Unico Hommes wrote:

>
> Look at the implementation of CacheManager.create(1)
>
> 1. http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=107066391625123&w=2
>

Sorry this was not supposed to be related. The above link is an 
explanation of the current Store pattern in Cocoon. 1 in 
CacheManager.create(1) is the number of arguments of the method.

--
Unico


Re: EHDefaultStore

Posted by Unico Hommes <un...@hippo.nl>.
On 3-dec-04, at 13:12, Jon Evans wrote:

> Hi Unico,
>
> On 2 Dec 2004, at 13:35, Unico Hommes wrote:
>
>>
>> On 2-dec-04, at 13:13, Jon Evans wrote:
>>
>>> I needed a cache for part of my webapp.  Basically I can look up 
>>> lists of things, based on a number of parameters.  I put all the 
>>> parameters into a Serializable class which becomes the key.  If it 
>>> isn't in the cache then I create a new object using a stored 
>>> procedure and add it to the cache.  The stored procedure takes about 
>>> 500ms, hence the need for the cache.
>>>
>>> I had to create my own "version" of EHDefaultStore, specific to my 
>>> app, because I didn't want an eternal cache.  I expire items after 5 
>>> minutes so that a db hit is forced (in case the data has been 
>>> updated).  Although EHDefaultStore takes many config parameters, it 
>>> doesn't have eternal, timeToLive or timeToIdle, and is hard coded to 
>>> always create an eternal cache.
>>>
>>> My questions:
>>>
>>> 1) Any reason why those parameters can't be added?  Then I could 
>>> have just configured my own instance in cocoon.xconf with a 
>>> different role name to the default.
>
>> EHDefaultStore is eternal by design. Having a store that would take 
>> care of expiration itself does not fit well with the way Cocoon uses 
>> and manages its stores. In order to open up the implementation to 
>> other uses than that of Cocoon it would be best to follow the same 
>> pattern as DefaultStore is doing. That is, move the current 
>> EHDefaultStore to AbstractEHStore and have EHDefaultStore extend 
>> AbstractEHStore and hard-code / overide some of the parameter 
>> settings.
>
> Sounds like a good idea.  Shall I do that & submit the patch? (stupid 
> question...) :-)
>

Yes please :-)

>>> 2) EHDefaultStore configures a CacheManager from an xml file, but 
>>> then creates the Cache object itself using the long Cache() 
>>> constructor.
>>> From my understanding of the EHCache docs, the xml file is used to 
>>> set the defaults for if a Cache object is created by the 
>>> CacheManager itself, which isn't being done in EHDefaultStore.
>>> We might just as well use
>>>
>>> CacheManager cacheManager = CacheManager.create(); // or 
>>> getInstance()
>>>
>>> even if the values in ehcache.xml are changed, it will make no 
>>> difference because each Cache is programatically created using 
>>> specific values for each property.  So we don't need it.
>>>
>>
>> Yes, we need it. IIRC some settings can only be specified in the 
>> descriptor file. Most notably the filesystem location of the 
>> disk-based cache. If you look at the EHDefaultStore code you can see 
>> that it relies on the fact that disk based cache location is 
>> configured to be the java.io.tmpdir system property.
>
> OK.  Incidentally, the code also includes:
>
> System.setProperty("java.io.tmpdir", directoryPath);
>
> is that a good idea?  Any component starting after EHDefaultStore 
> would see that new value for tmpdir, which could be different to the 
> one set when the JVM started up.  I don't think it could cause 
> problems but you could potentially end up with temp files in two 
> different places.  Or have I misread it again?
>
>

No, you are absolutely right. This is a hazardous situation. 
Unfortunately, I don't think there is an easy way around this. The only 
thing I can think of ATM is to manipulate the configuration file's 
input stream to insert the right value.

--
Unico


Re: EHDefaultStore

Posted by Jon Evans <jo...@misgl.com>.
Hi Unico,

On 2 Dec 2004, at 13:35, Unico Hommes wrote:

>
> On 2-dec-04, at 13:13, Jon Evans wrote:
>
>> I needed a cache for part of my webapp.  Basically I can look up 
>> lists of things, based on a number of parameters.  I put all the 
>> parameters into a Serializable class which becomes the key.  If it 
>> isn't in the cache then I create a new object using a stored 
>> procedure and add it to the cache.  The stored procedure takes about 
>> 500ms, hence the need for the cache.
>>
>> I had to create my own "version" of EHDefaultStore, specific to my 
>> app, because I didn't want an eternal cache.  I expire items after 5 
>> minutes so that a db hit is forced (in case the data has been 
>> updated).  Although EHDefaultStore takes many config parameters, it 
>> doesn't have eternal, timeToLive or timeToIdle, and is hard coded to 
>> always create an eternal cache.
>>
>> My questions:
>>
>> 1) Any reason why those parameters can't be added?  Then I could have 
>> just configured my own instance in cocoon.xconf with a different role 
>> name to the default.

> EHDefaultStore is eternal by design. Having a store that would take 
> care of expiration itself does not fit well with the way Cocoon uses 
> and manages its stores. In order to open up the implementation to 
> other uses than that of Cocoon it would be best to follow the same 
> pattern as DefaultStore is doing. That is, move the current 
> EHDefaultStore to AbstractEHStore and have EHDefaultStore extend 
> AbstractEHStore and hard-code / overide some of the parameter 
> settings.

Sounds like a good idea.  Shall I do that & submit the patch? (stupid 
question...) :-)

>> 2) EHDefaultStore configures a CacheManager from an xml file, but 
>> then creates the Cache object itself using the long Cache() 
>> constructor.
>> From my understanding of the EHCache docs, the xml file is used to 
>> set the defaults for if a Cache object is created by the CacheManager 
>> itself, which isn't being done in EHDefaultStore.
>> We might just as well use
>>
>> CacheManager cacheManager = CacheManager.create(); // or getInstance()
>>
>> even if the values in ehcache.xml are changed, it will make no 
>> difference because each Cache is programatically created using 
>> specific values for each property.  So we don't need it.
>>
>
> Yes, we need it. IIRC some settings can only be specified in the 
> descriptor file. Most notably the filesystem location of the 
> disk-based cache. If you look at the EHDefaultStore code you can see 
> that it relies on the fact that disk based cache location is 
> configured to be the java.io.tmpdir system property.

OK.  Incidentally, the code also includes:

System.setProperty("java.io.tmpdir", directoryPath);

is that a good idea?  Any component starting after EHDefaultStore would 
see that new value for tmpdir, which could be different to the one set 
when the JVM started up.  I don't think it could cause problems but you 
could potentially end up with temp files in two different places.  Or 
have I misread it again?

Thanks,

Jon


Re: EHDefaultStore

Posted by Unico Hommes <un...@hippo.nl>.
On 2-dec-04, at 13:13, Jon Evans wrote:

> Hi,
>
> I needed a cache for part of my webapp.  Basically I can look up lists 
> of things, based on a number of parameters.  I put all the parameters 
> into a Serializable class which becomes the key.  If it isn't in the 
> cache then I create a new object using a stored procedure and add it 
> to the cache.  The stored procedure takes about 500ms, hence the need 
> for the cache.
>
> I had to create my own "version" of EHDefaultStore, specific to my 
> app, because I didn't want an eternal cache.  I expire items after 5 
> minutes so that a db hit is forced (in case the data has been 
> updated).  Although EHDefaultStore takes many config parameters, it 
> doesn't have eternal, timeToLive or timeToIdle, and is hard coded to 
> always create an eternal cache.
>
> My questions:
>
> 1) Any reason why those parameters can't be added?  Then I could have 
> just configured my own instance in cocoon.xconf with a different role 
> name to the default.
>

EHDefaultStore is eternal by design. Having a store that would take 
care of expiration itself does not fit well with the way Cocoon uses 
and manages its stores. In order to open up the implementation to other 
uses than that of Cocoon it would be best to follow the same pattern as 
DefaultStore is doing. That is, move the current EHDefaultStore to 
AbstractEHStore and have EHDefaultStore extend AbstractEHStore and 
hard-code / overide some of the parameter settings.

> 2) EHDefaultStore configures a CacheManager from an xml file, but then 
> creates the Cache object itself using the long Cache() constructor.
> From my understanding of the EHCache docs, the xml file is used to set 
> the defaults for if a Cache object is created by the CacheManager 
> itself, which isn't being done in EHDefaultStore.
> We might just as well use
>
> CacheManager cacheManager = CacheManager.create(); // or getInstance()
>
> even if the values in ehcache.xml are changed, it will make no 
> difference because each Cache is programatically created using 
> specific values for each property.  So we don't need it.
>

Yes, we need it. IIRC some settings can only be specified in the 
descriptor file. Most notably the filesystem location of the disk-based 
cache. If you look at the EHDefaultStore code you can see that it 
relies on the fact that disk based cache location is configured to be 
the java.io.tmpdir system property.

> 3) a CacheManager can manage more than one Cache, yet we create one 
> per instance of EHDefaultStore.
> OK, at the moment there is only one instance of EHDefaultStore (I 
> think?), but if it's made more generic (see 1) then there could be 
> more.  We could have a static CacheManager shared between them all.
> This does however mean that we'd need an instance count so that the 
> last instance could call cacheManager.shutdown() (and the first client 
> would call create()).  But then we already do have an instance count 
> which is used in EHDefaultStore to generate a new name each time the 
> constructor is called.
>

Look at the implementation of CacheManager.create(1) the CacheManager 
is already a shared instance. Calling CacheManager.create() with a 
different config file after it has already been initialized previously 
has no effect. Another reason to not have the configuration file be 
configurable.


1. http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=107066391625123&w=2

--
Unico


Re: EHDefaultStore

Posted by Jorg Heymans <jh...@domek.be>.

Jon Evans wrote:
> Hi Jorg,
> 
<snip/>
> 
> I've just checked out the ehcache source and confirmed what Unico said 
> in his reply: CacheManager is a singleton, so whichever component starts 
> up first (yours or EHDefaultCache) will configure the cache manager.  
> The second one to start up will just end up using the existing instance, 
> it won't be reconfigured.  I'm sure this will work fine 90% of the time, 
> but I bet it would be hard to track down the reason why it's suddenly 
> ignoring changes you've made in your config file (i.e. it already read 
> the other one).
> 
> This is another reason why I think we need a system-wide ehcache 
> component, which is used by EHDefaultCache and any other instances 
> needed by specific applications...
+1

> 
>> How about making cocoon use an explicit named cache instead of the 
>> default one ?
+1

If we go ahead and do this, then it would make sense to have ehcache.xml 
out in the open instead of buried cocoon jar. Alternatively you could 
add the posibility to configure different ehcache configurations in the 
component config of EHDefaultStore (maybe it allows this already?)

Regards
Jorg


Re: EHDefaultStore

Posted by Jon Evans <jo...@misgl.com>.
Hi Unico,

On 3 Dec 2004, at 12:52, Unico Hommes wrote:

>
> On 3-dec-04, at 13:27, Jon Evans wrote:
>

>> This is another reason why I think we need a system-wide ehcache 
>> component, which is used by EHDefaultCache and any other instances 
>> needed by specific applications...
>>
>
> I don't understand. What is wrong with the Store interface?

Sorry, I wasn't being very clear.  I think I meant:

This is another reason why I think we need a system-wide ehcache 
component, which is used by any Store component which wants to be 
backed by an ehcache (e.g. EHDefaultCache and any other instances 
needed by specific applications).

i.e. there is one EHCache component which configures CacheManager from 
ehcache.xml.  Then any clients (StoreS like EHDefaultCache) that want 
to use ehcache can call a method on the EHCache component to add a new 
Cache to the CacheManager.

I envisage something like you said in an earlier email:

split out EHDefaultCache into AbstractEHCache, which can create any 
type of Cache, EHDefaultCache which extends it and is hard coded to 
create an eternal cache, and EHCache which can be configured in 
cocoon.xconf to create any sort of Cache supported by EHCache.



Jon


Re: EHDefaultStore

Posted by Unico Hommes <un...@hippo.nl>.
On 3-dec-04, at 13:27, Jon Evans wrote:

> Hi Jorg,
>
> On 2 Dec 2004, at 13:38, Jorg Heymans wrote:
>
>> Jon Evans wrote:
>>> I had to create my own "version" of EHDefaultStore, specific to my 
>>> app, because I didn't want an eternal cache.  I expire items after 5 
>>> minutes so that a db hit is forced (in case the data has been 
>>> updated).  Although EHDefaultStore takes many config parameters, it 
>>> doesn't have eternal, timeToLive or timeToIdle, and is hard coded to 
>>> always create an eternal cache.
>> I'm not sure on the exact role of EHDefaultStore (allright I didn't 
>> know it even existed).
>>
>> I am using my "own" cachemanager created as follows
>>
>> CacheManager.create(new FileInputStream(new File( 
>> "/WEB-INF/classes/ehcache.xml")));
>>
>> In this file i configure my caches and also provide a default cache.
>> I then create my configured caches with 
>> manager.getCache("myconfiguredcache1")
>>
>> (a side effect of this is that Cocoon dumps it's ehcache in the dir 
>> configured in my ehcache.xml). This means it's using the default 
>> cache which is a bad thing IMHO.
>
>
> I've just checked out the ehcache source and confirmed what Unico said 
> in his reply: CacheManager is a singleton, so whichever component 
> starts up first (yours or EHDefaultCache) will configure the cache 
> manager.  The second one to start up will just end up using the 
> existing instance, it won't be reconfigured.  I'm sure this will work 
> fine 90% of the time, but I bet it would be hard to track down the 
> reason why it's suddenly ignoring changes you've made in your config 
> file (i.e. it already read the other one).
>
> This is another reason why I think we need a system-wide ehcache 
> component, which is used by EHDefaultCache and any other instances 
> needed by specific applications...
>

I don't understand. What is wrong with the Store interface?

--
Unico


Re: EHDefaultStore

Posted by Jon Evans <jo...@misgl.com>.
Hi Jorg,

On 2 Dec 2004, at 13:38, Jorg Heymans wrote:

> Jon Evans wrote:
>> I had to create my own "version" of EHDefaultStore, specific to my 
>> app, because I didn't want an eternal cache.  I expire items after 5 
>> minutes so that a db hit is forced (in case the data has been 
>> updated).  Although EHDefaultStore takes many config parameters, it 
>> doesn't have eternal, timeToLive or timeToIdle, and is hard coded to 
>> always create an eternal cache.
> I'm not sure on the exact role of EHDefaultStore (allright I didn't 
> know it even existed).
>
> I am using my "own" cachemanager created as follows
>
> CacheManager.create(new FileInputStream(new File( 
> "/WEB-INF/classes/ehcache.xml")));
>
> In this file i configure my caches and also provide a default cache.
> I then create my configured caches with 
> manager.getCache("myconfiguredcache1")
>
> (a side effect of this is that Cocoon dumps it's ehcache in the dir 
> configured in my ehcache.xml). This means it's using the default cache 
> which is a bad thing IMHO.


I've just checked out the ehcache source and confirmed what Unico said 
in his reply: CacheManager is a singleton, so whichever component 
starts up first (yours or EHDefaultCache) will configure the cache 
manager.  The second one to start up will just end up using the 
existing instance, it won't be reconfigured.  I'm sure this will work 
fine 90% of the time, but I bet it would be hard to track down the 
reason why it's suddenly ignoring changes you've made in your config 
file (i.e. it already read the other one).

This is another reason why I think we need a system-wide ehcache 
component, which is used by EHDefaultCache and any other instances 
needed by specific applications...

> How about making cocoon use an explicit named cache instead of the 
> default one ?

...which is pretty much what you're saying there.

Jon


Re: EHDefaultStore

Posted by Jorg Heymans <jh...@domek.be>.
Hi Jon,

A few loose thoughts here, i just dealt with similar issues last week.


Jon Evans wrote:
> 
> I had to create my own "version" of EHDefaultStore, specific to my app, 
> because I didn't want an eternal cache.  I expire items after 5 minutes 
> so that a db hit is forced (in case the data has been updated).  
> Although EHDefaultStore takes many config parameters, it doesn't have 
> eternal, timeToLive or timeToIdle, and is hard coded to always create an 
> eternal cache.
I'm not sure on the exact role of EHDefaultStore (allright I didn't know 
it even existed).

I am using my "own" cachemanager created as follows

CacheManager.create(new FileInputStream(new File( 
"/WEB-INF/classes/ehcache.xml")));

In this file i configure my caches and also provide a default cache.
I then create my configured caches with 
manager.getCache("myconfiguredcache1")

(a side effect of this is that Cocoon dumps it's ehcache in the dir 
configured in my ehcache.xml). This means it's using the default cache 
which is a bad thing IMHO.

> 2) EHDefaultStore configures a CacheManager from an xml file, but then 
> creates the Cache object itself using the long Cache() constructor.
>  From my understanding of the EHCache docs, the xml file is used to set 
> the defaults for if a Cache object is created by the CacheManager 
> itself, which isn't being done in EHDefaultStore.
true, just use the default factory method for creating the cache.
> 
> 3) a CacheManager can manage more than one Cache, yet we create one per 
> instance of EHDefaultStore.
> OK, at the moment there is only one instance of EHDefaultStore (I 
> think?), but if it's made more generic (see 1) then there could be 
> more.  We could have a static CacheManager shared between them all.

> This does however mean that we'd need an instance count so that the last 
> instance could call cacheManager.shutdown() (and the first client would 
> call create()).  But then we already do have an instance count which is 
> used in EHDefaultStore to generate a new name each time the constructor 
> is called.
Doesn't ehcache have finalizer hooks on the cachemanager ? Or is cocoon 
shutting the cachemanager down properly? Reason i'm asking is that my 
cache gets shutdown properly even when I don't shutdown the manager.


How about making cocoon use an explicit named cache instead of the 
default one ?

Regards,
Jorg