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