I have a value in a KVM which I am using to store the rate limit for a Spike Arrest.
In my proxy, I have a KVM Operations Policy to retrieve it:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <KeyValueMapOperations async="false" continueOnError="false" enabled="true" name="KV-GetSpikeArrestLimitValue" mapIdentifier="SpikeArrest"> <DisplayName>GetSpikeArrestLimitValue</DisplayName> <Properties/> <ExclusiveCache>false</ExclusiveCache> <ExpiryTimeInSecs>10</ExpiryTimeInSecs> <Get assignTo="spikeArrestValue"> <Key> <Parameter>SpikeArrestValue</Parameter> </Key> </Get> <Scope>environment</Scope> </KeyValueMapOperations>
When I am changing the KVM value, the execution of this policy doesn't seem to pick up the change. My understanding of the ExpiryTimeInSecs parameter is that it should refresh after 10 seconds, but this isn't the case. Even deleting the KVM doesn't help; the old value is still referenced.
The KVM concept loses it's value in this Use Case if we can't replicate updates relatively quickly. The danger is that we knock the value down low during a difficult period, then knock it back up again, but we have no control over when the value is replicated into cache.
Am I missing something?
Solved! Go to Solution.
John - to answer your question, yes, you are missing something!
The behavior you are seeing is confusing but there is a simple explanation.
You had a prior version KVM-Get policy that specified an ExpiryTimeInSecs of something more than "Several hours". Maybe you used 86400, maybe something larger. When you ran the KVM-Get the first time, it populated the cache with the TTL of 86400 (or whatever you used).
The TTL of 86400 is often the used because at one point, that value was used in the same policy configuration in our documentation!
Then, you modified the KVM-Get policy to specify 10 seconds for ExpiryTimeInSecs. You re-ran the KVM-Get expecting to see the data being cached for only 10 seconds. But that expectation is wrong.
The cache would be kept for only 10 seconds IF the cache were not already populated. But the element you are trying to read is already in cache, and that cached element has an expiry (aka TTL), which you cannot change, or even see. So a KVM-Get continues to return what you consider to be "stale" data.
To escape this situation, you have some options.
Either way will lead you to joy.
Hi @John Ferguson - This should ideally not happen. I tried the same code you have and it works as expected. I have my trace ON - I can see 30ps coming from KVM. While the trace is still ON, I updated the KVM value to 50ps and hit the proxy to get the new 50ps.
Can you confirm if you are changing the value of the KVM entry in the correct environment ? Its also possible that you are updating the entries in the wrong environment. I have done a few times in a hurry :0
Hello @Sai Saran Vaidyanathan.
Just to be absolutely sure I went back and checked. I'm definitely updating in the same environment.
Thanks for confirming @John Ferguson. Is this on Cloud ? Can you share your and proxy info by using the Ask the Expert option on the right
John - to answer your question, yes, you are missing something!
The behavior you are seeing is confusing but there is a simple explanation.
You had a prior version KVM-Get policy that specified an ExpiryTimeInSecs of something more than "Several hours". Maybe you used 86400, maybe something larger. When you ran the KVM-Get the first time, it populated the cache with the TTL of 86400 (or whatever you used).
The TTL of 86400 is often the used because at one point, that value was used in the same policy configuration in our documentation!
Then, you modified the KVM-Get policy to specify 10 seconds for ExpiryTimeInSecs. You re-ran the KVM-Get expecting to see the data being cached for only 10 seconds. But that expectation is wrong.
The cache would be kept for only 10 seconds IF the cache were not already populated. But the element you are trying to read is already in cache, and that cached element has an expiry (aka TTL), which you cannot change, or even see. So a KVM-Get continues to return what you consider to be "stale" data.
To escape this situation, you have some options.
Either way will lead you to joy.
I followed your first option and that seems to have done the trick. We're at a stage of development where the KVM name is not locked in stone, so we can just do this.
I only ever add KVM values from the Edge UI and I don't remember setting a long expiry date in any of the KVMO policies, but it's possible me or one of my devs did it during a sandboxing exercise without realising. Something to be mindful of though.
Many thanks.
There always has scenario to make an urgent changes on KVM and it must be effect upon submission.
Ideally, apigee should invalidate the cache if an entry of KVM is changed.
Option 2 in my post does exactly this.
Another option is not to use the caching built into the KeyValueMapOperations but to use the Apigee Caching policies themselves. This gives you much more control without renaming and things like that.
There is a detailed example here: https://community.apigee.com/articles/24906/a-pattern-for-caching-kvm-values.html