Invalidate cache policy clears all entries with PurgeChildEntries=true

I have a proxy that uses a populate cache policy to cache the response content.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PopulateCache async="false" continueOnError="false" enabled="true" name="PC-PopulateCache">
<DisplayName>PC-PopulateCache</DisplayName>
<Properties/>
<CacheResource>users-cache</CacheResource>
<Source>response.content</Source>
<CacheKey>
<Prefix/>
<KeyFragment ref="request.uri"/>

<KeyFragment ref="userid"/>
</CacheKey>
<Scope>Global</Scope>
<ExpirySettings>
<TimeoutInSec>3600</TimeoutInSec>
</ExpirySettings>
</PopulateCache>

 

I call an endpoint of another proxy to invalidate the cache. This is my invalidate cache policy with PurgeChildEntries=true.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<InvalidateCache async="false" continueOnError="false" enabled="true" name="IC-InvalidateCache">
<DisplayName>IC-InvalidateCache</DisplayName>
<CacheKey>

<Prefix />
<KeyFragment ref="userid"/>
</CacheKey>
<CacheResource>users-cache</CacheResource>
<Scope>Global</Scope>
<PurgeChildEntries>true</PurgeChildEntries>
</InvalidateCache>

 

I am expecting all entries related to <KeyFragment ref="userid"/> to be removed. However, all entries in the cache are being removed. 

With <PurgeChildEntries>true</PurgeChildEntries>, shouldn't it remove only related entries from the cache instead of the entire cache?

0 6 312
6 REPLIES 6

I am expecting all entries related to <KeyFragment ref="userid"/> to be removed. However, all entries in the cache are being removed. With <PurgeChildEntries>true</PurgeChildEntries>, shouldn't it remove only related entries from the cache instead of the entire cache?

Hmm my understanding of the function of InvalidateCache is different than what is documented. I believe that InvalidateCache clears the cache of all entries that share the same Prefix. I looked in the documentation just now and could not find a statement describing this behavior. On the contrary, I found this statement regarding PurgeChildEntries:

true to purge cache entries that share the value set by a <KeyFragment> element configured for this policy. Values in other parts of the cache key, such as in <Prefix> elements, are not considered.

I think this is incorrect. I think this sentence has transposed the words KeyFragment and Prefix. I think the correct statement is:

true to purge cache entries that share the value set by a <Prefix> element configured for this policy. Values in other parts of the cache key, such as in <KeyFragment> elements, are not considered.

If I am correct, then the policy is behaving as expected (but not as documented) because you have no Prefix. Therefore the policy as you have configured it invalidates all entries.

If you have multiple PopulateCache policies that use prefix "xyz", plus some other KeyFragments, and then later use InvalidateCache with Prefix = xyz , and no KeyFragments, my expectation is that all the cache entries that were loaded with Prefix = xyz will be invalidated. Keep in mind the Prefix is static, hardcoded. (You can't refer to a variable in the Prefix element. You cannot use a ref= ).

In any case, the InvalidateCache is not going to work according to your expectations. You wrote, "I am expecting all entries related to<KeyFragment ref="userid"/> to be removed." And I suspect you mean that, if any entry uses a KeyFragment with that userid, then that entry will be removed. And as far as I know, the cache within Apigee does not work that way. InvalidateCache works with Prefix only, it cannot remove cache entries "related to" a particular key fragment. The key fragments are used only to create the actual key. Apigee does not store the key fragments. So there is no way for Apigee to track which key fragments have been used with which cache entries. Apigee tracks which KEYS are used with the cache entries, but not the constituent key fragments. This is a small difference, but it's important. It means you can invalidate by key, but not by key fragment. There is just one exception - removing by prefix.

I'd appreciate it if you could test this yourself. See if loading things into the cache with a given prefix, and then invalidating based on that prefix, works for you the way I expect and described. Pending confirmation by you and by me, I'll get the documentation changed.

The actual behavior with respect to invalidating cache entries within Apigee may not line up with the way you wish the Apigee cache behaved. If that's the case, you may need to rethink your key structure or the value structure, or use a different cache, something external to Apigee.


Update: I just tried this and yes, it behaves the way I had expected and described. The documentation is incorrect. I'll get that fixed.

@dchiesa1 I have tested the scenario adding prefix in the populate cache and invalidating the cache based on that prefix I added, it worked as you mentioned.

Great, thank you! for that confirmation. I am working on an update to the documentation to correct the statement I highlighted above.

Hi @dchiesa1, I was wondering why Prefix cannot use ref i.e. a <Prefix ref="request.userid"/>?

I don’t know why that is the case. It’s just designed that way. 

Ok thanks for answering @dchiesa1.  
If I can ask another question, for somaghoshatl's use case of wanting to clear all records related to a user id (where the user id is only known at runtime) this isn't possible using purge child entries = true because prefix's are static values?
I say 'isn't possible' in a use case where there are multiple GET requests accessing the same underlying customer data and therefore there are multiple / different cache keys of the customer's data to be invalidated.