CacheInfo not available in GlobalRequestFilter

Hello,

mythz very quickly answered my original question on SO (link below in case others are interested), but I had a follow up question that’s more specific.

I am trying access the cacheInfo for a request in a GlobalRequestFilter, but it is always null. In the code below, ci is always null. The same code works as a response filter, but does not solve my original problem (presumably because the incorrect cache key has already been looked up in the cache).

this.GlobalRequestFilters.Add((req, res, responseDto) =>
{
var ci = (CacheInfo)req.GetItem(Keywords.CacheInfo);
});

Original question: regarding how to change the cache key of the url-based CacheControl attribute- :

You would need to change the priority to <0 so it’s executed before the global request filters, e.g:

[CacheResponse(Priority = -1, Duration = 3600)]

Thank you. That helped a bit.

My global request filter is executing, and my modified cache key is getting written into the cache (I’m removing the timestamp from the url), but the Factory method is still being called for the service every time (the cache isn’t being used).

What factory method? the GlobalRequestFilters? yes they’re executed for every Service Request so CacheInfo is only going to be populated for requests using a Request Filter Attribute which populates them like [CacheResponse].

No I mean the factory method that generates my response from the database. This shouldn’t execute a second time if the cache is being used.

I will try and create a stand-alone example if this isn’t clear, but here’s the example

Call Service with a url like /svc?_nnnnnn, where the parameter is a timestamps.

My new global request filter strips the timestamp off the cache key. Cache key is res:/svc. Service response is populated from database

Call Service again, this time changing the nnnnn value (new timestamp).

Global request filter runs again, strips number off cache key.

Service response is again populated from database, I would expect the cache to be used.

Please provide a stand-alone example I can run to repro the behavior.

Project example at box link below. Thank you.

https://indians.box.com/s/op1hmu7gs6rnarnakct92zp5h6391j9y

Yeah it needs to check if the cache exists with the modified key by calling HandleValidCache() as seen below:

this.GlobalRequestFiltersAsync.Add(async (req, res, requestDto) =>
{
    var cacheInfo = (CacheInfo)req.GetItem(Keywords.CacheInfo);
    if (cacheInfo?.KeyBase != null)
    {
        var iPos = cacheInfo.KeyBase.IndexOf("?_=");
        if (iPos >= 0)
        {
            cacheInfo.KeyBase = cacheInfo.KeyBase.Substring(0, iPos);
        }
        else
        {
            iPos = cacheInfo.KeyBase.IndexOf("&_=");
            if (iPos >= 0)
            {
                cacheInfo.KeyBase = cacheInfo.KeyBase.Substring(0, iPos);
            }
        }
        await req.HandleValidCache(cacheInfo);
    }
});
1 Like

Thanks, issue is fixed.

Incidentally, I am using this same code to dynamically change my cache expiry time, something I had thought I had lost when I switched from .ToOptimizedResult() to the more declarative CacheResponse. I have a special cache duration that’s something like “if it’s before noon, cache 10 minutes, and if it’s after noon, cache the rest of the day”.

To enable this, I use a special duration of 59 seconds in my cacheresponse (behind a constant).

 [CacheResponse(Priority = -1, Duration = CacheExpirySeconds.DailyLoadIndicator)]

Then in the new GlobalRequestFilter, I look for that duration and change it to the more custom cache expiry time.

  this.GlobalRequestFiltersAsync.Add(async (req, res, responseDto) =>
            {
                var cacheInfo = (CacheInfo)req.GetItem(Keywords.CacheInfo);
                if (cacheInfo != null )
                {
                    if (cacheInfo.ExpiresIn?.TotalSeconds == CacheExpirySeconds.DailyLoadIndicator)
                    {
                        cacheInfo.ExpiresIn = CacheExpiryTime.DailyLoad();
                    }
                    await req.HandleValidCache(cacheInfo);
                }
            });

I wanted to share in case anyone else was wondering if they could dynamically change their cache expiry time.

1 Like