You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Alexander Klimetschek <al...@mindquarry.com> on 2007/01/23 18:55:21 UTC

Keys for cache are insufficient when using multiple block servlets

Hi,

when using multiple block-servlets in one cocoon application (2.2), they 
will all use the same EHDefaultStore as cache. If there are similar 
matchers in the sitemaps, eg. images/header.png, the key for the cached 
resource will be the same for both blocks (just images/header.png), and, 
as the cache is global, the same cached object will be returned for both 
requests. This happens with expires-caching.

This should be fixed by adding a unique key prefix for each 
block-servlet or by one cache per block-servlet, but I do not know how 
to configure this.

Alex

-- 
Alexander Klimetschek
http://www.mindquarry.com


Re: Keys for cache are insufficient when using multiple block servlets

Posted by Daniel Fagerstrom <da...@nada.kth.se>.
Alexander Klimetschek skrev:
> I just wrote a pipeline that fixes my other problem [1] (by selecting 
> between two different pipelines based on the actual running mode) and 
> included this fix for the caching key which works fine. I have to pass 
> through each of the ProcessingPipeline methods anyway and in each call 
> that has the Environment as parameter I change the uri prefix set in it:
> 
> private void fixEnvironmentForCachingPrefix(Environment env) {
>     if (this.fixMissingCachingPrefixWithBlockServlets &&
>         (env.getURIPrefix() == null || env.getURIPrefix().equals(""))) {
> 
>         ServletContext context =
>             BlockCallStack.getCurrentBlockContext();
> 
>         if (context instanceof BlockContext) {
>             // use the mount path of the block as the prefix
>             String mountPath =
>                 ((BlockContext) context).getMountPath() + "/";
>             env.setURI(mountPath, env.getURI());
>         }
>     }
> }
> 
> The trick is using the static method 
> BlockCallStack.getCurrentBlockContext() and using the mount path as a 
> unique and short URI prefix, which is then used by the caching pipeline 
> implemenations. You are free to consider it as a dirty hack ;-)

I guess that it currently is hard to solve the problem without hacks.

I plan to create a special Spring "call scope" (Spring 2.0 allows for 
custom scopes). The call scope will embed the block call stack (and 
maybe also the sitemap call stack) in a way that make it possible to use 
dependency injection rather than static methods for getting dynamic info 
like the current call context.

/Daniel


Re: Keys for cache are insufficient when using multiple block servlets

Posted by Alexander Klimetschek <al...@mindquarry.com>.
I just wrote a pipeline that fixes my other problem [1] (by selecting 
between two different pipelines based on the actual running mode) and 
included this fix for the caching key which works fine. I have to pass 
through each of the ProcessingPipeline methods anyway and in each call 
that has the Environment as parameter I change the uri prefix set in it:

private void fixEnvironmentForCachingPrefix(Environment env) {
     if (this.fixMissingCachingPrefixWithBlockServlets &&
         (env.getURIPrefix() == null || env.getURIPrefix().equals(""))) {

         ServletContext context =
             BlockCallStack.getCurrentBlockContext();

         if (context instanceof BlockContext) {
             // use the mount path of the block as the prefix
             String mountPath =
                 ((BlockContext) context).getMountPath() + "/";
             env.setURI(mountPath, env.getURI());
         }
     }
}

The trick is using the static method 
BlockCallStack.getCurrentBlockContext() and using the mount path as a 
unique and short URI prefix, which is then used by the caching pipeline 
implemenations. You are free to consider it as a dirty hack ;-)

Alex

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

Vadim Gritsenko schrieb:
> Daniel Fagerstrom wrote:
>> Alexander Klimetschek skrev:
>>> Hi,
>>>
>>> when using multiple block-servlets in one cocoon application (2.2), 
>>> they will all use the same EHDefaultStore as cache. If there are 
>>> similar matchers in the sitemaps, eg. images/header.png, the key for 
>>> the cached resource will be the same for both blocks (just 
>>> images/header.png), and, as the cache is global, the same cached 
>>> object will be returned for both requests. This happens with 
>>> expires-caching.
>>>
>>> This should be fixed by adding a unique key prefix for each 
>>> block-servlet or by one cache per block-servlet, but I do not know 
>>> how to configure this.
>>
>> The Spring bean name for the block-servlet would work fine as an 
>> unique bean prefix.
> 
> Prefix from parent sitemap used to be part of the key, IIRC. Works even 
> better.
> 
>> And it is available from ServletConfig.getServletName() in the 
>> block-servlet. The next and more complicated question is how to get 
>> the identifier to the caching key ...
> 
> .... or how to fix the regression.
> 
> Vadim
> 


-- 
Alexander Klimetschek
http://www.mindquarry.com


Re: Keys for cache are insufficient when using multiple block servlets

Posted by Vadim Gritsenko <va...@reverycodes.com>.
Daniel Fagerstrom wrote:
> Alexander Klimetschek skrev:
>> Hi,
>>
>> when using multiple block-servlets in one cocoon application (2.2), 
>> they will all use the same EHDefaultStore as cache. If there are 
>> similar matchers in the sitemaps, eg. images/header.png, the key for 
>> the cached resource will be the same for both blocks (just 
>> images/header.png), and, as the cache is global, the same cached 
>> object will be returned for both requests. This happens with 
>> expires-caching.
>>
>> This should be fixed by adding a unique key prefix for each 
>> block-servlet or by one cache per block-servlet, but I do not know how 
>> to configure this.
> 
> The Spring bean name for the block-servlet would work fine as an unique 
> bean prefix.

Prefix from parent sitemap used to be part of the key, IIRC. Works even better.

> And it is available from ServletConfig.getServletName() in 
> the block-servlet. The next and more complicated question is how to get 
> the identifier to the caching key ...

... or how to fix the regression.

Vadim

Re: Keys for cache are insufficient when using multiple block servlets

Posted by Daniel Fagerstrom <da...@nada.kth.se>.
Alexander Klimetschek skrev:
> Hi,
> 
> when using multiple block-servlets in one cocoon application (2.2), they 
> will all use the same EHDefaultStore as cache. If there are similar 
> matchers in the sitemaps, eg. images/header.png, the key for the cached 
> resource will be the same for both blocks (just images/header.png), and, 
> as the cache is global, the same cached object will be returned for both 
> requests. This happens with expires-caching.
> 
> This should be fixed by adding a unique key prefix for each 
> block-servlet or by one cache per block-servlet, but I do not know how 
> to configure this.

The Spring bean name for the block-servlet would work fine as an unique 
bean prefix. And it is available from ServletConfig.getServletName() in 
the block-servlet. The next and more complicated question is how to get 
the identifier to the caching key ...

/Daniel