How do I deal with KVM cache when updating the Key Value Map with a PUT operation?

Is there a way to mimic the PUT operation in the KVM Operations policy through a management API?

Here is my usecase -

I have a set of KVMs that get updated not so often, but periodically.

1. Backend Authorization Key rotation (happens once in 45 days)

2. Maintenance Mode settings for the backend (irregular, but can assume once in 3 months)

3. Backend account credentials update for legacy systems (once in 60 days)

The operations team does the update on the Management UI, however the cache will not reflect the values until the current expiry (which is set to 1 hour, 1 day etc)

I checked a few other posts - mapidentifier cannot be set to a dynamic value, so I cant have a single utility proxy that can update the entries and values based on an input KVM name.

I have tried a not so clean way of having a single proxy which has multiple KVM policies (one for each mapidentifier) and conditions to execute the corresponding policy based on a request payload element which has the KVM name. The issue is, if the number of KVMs(right now 3) that need periodic updates keep increasing, I have to keep adding more KVM operations policy to this proxy.

Can anyone suggest any options on how to handle this scenario?

0 4 821
4 REPLIES 4

Suggestion is, keep the cache TTL time, low.

Try 5 minutes.

Is that not sufficient?

Ps: you didn't characterize the problem beyond this:

however the cache will not reflect the values until the current expiry (which is set to 1 hour, 1 day etc)

So the simple solution to that is to shrink the TTL.

If there is some other problem you're trying to avoid, then you may need a more nuanced solution. But you'll need to describe the specific problem with details, if you would like to discuss such possible solutions.

As one example of more nuanced solutions, let's consider rotating credentials. Doing that, you can use 2 levels of KVM lookup. The first might be the "current credential ID". the second is the set of credentials that various IDs map to.

so you'd have 2 separate lookups in KVM. Rotation means:

  • add a credential entry to the KVM
  • update the current credential ID in the KVM

Proxies would first lookup the current credential ID using a fixed key of "currentCred" or something like that. And then they'd retrieve ABC123. Then the proxy could use an additional policy doing a KVM GET with a variable Key , using that credential ID as a Parameter element.

After the KVM cache expires you can remove the old credential IDs.

@Dino-at-Google - Thanks for your response

Ps: you didn't characterize the problem beyond this:

I do understand from the docs and the various posts that, the near real-time update of a KVM entry and internal cache update can only happen through the KVM-Operations PUT. I was hoping to build a utility proxy that can internally do the PUT operation for any KVM, by using a request payload indicating the KVM name and the entry to be updated. Unfortuantely, the mapidentifier cannot be set dynamically. So I was checking if there is a management API to do something like a KVM operations PUT for any KVM or some other way to mimic the PUT.

Back to the solutions you suggested -

I can try 5 minutes, won't that lead to - one call every 5 minutes to be slower and also open up a 5 minute window where we can have errors due to the old value read from the cache? [I am dealing with a payment API with considerable traffic in a 5 min window 😞 ]

Understand its a trade-off between the benefits of caching and the error count.

I am not sure if I followed the second approach you suggested. This is what I understood:

Lets say the KVM initially has

Key=>currentCred Value=> ABC123

Let's assume TTL is set to 5 minutes when this value is cached through fetch operation

Are you suggesting that I add another entry to the KVM, at the same time update the existing entry

Key=>updatedCred Value=>XYZ123

Key=>currentCred Value=>XYZ123

Then have some kind of conditions to check and use the updated value in the proxy?

Once the cache expiry happens, delete the entry updatedCred?

if there is a management API to do something like a KVM operations PUT for any KVM or some other way to mimic the PUT.

Confirming: there is none.

I can try 5 minutes, won't that lead to - one call every 5 minutes to be slower and also open up a 5 minute window where we can have errors due to the old value read from the cache?

Well it depends on what you update the KVM value to. Let's suppose the item in the KVM is an identifier to ... something. A discount code, a marketing program. The set of possible identifiers is: {X123, Y456}. In my scenario, when the value in the KVM entry is X123, then the API Proxy retrieves that value, then calls a SErviceCallout with the value X123 in the request, and receives back... something... through which the API Proxy operationalizes further flow.

Now you update the KVM to hold Y456. Before the cache is refreshed, the KVM Cache still contains X123. So the ServiceCallout is sent out with the value X123. We can design the system to continue to work, even though the KVM backing store has been updated, if the remote service gives a valid answer for X123. Eventually (5 minutes?) the KVM Cache gets refreshed and the ServiceCallout gets sent out with Y456. And the response from that is also valid. So all is good. There were no errors in the API Proxy.

I am not sure if I followed the second approach you suggested.

Let me try explaining again. I think it may be useful for you.

Let the KVM have these values at time T0:

key value
currentCredId ABC123
cred__ABC123 {"any" : "json", "here" : true }
cred__DEF780 {"any" : "different json", "here" : true }

Now the API Proxy is running. It has a KVM policy like this:

<KeyValueMapOperations name='KVM-GetCurrent' mapIdentifier='map1'>
  <Scope>environment</Scope>
  <ExpiryTimeInSecs>300</ExpiryTimeInSecs>
  <Get assignTo='currentCredId' >
    <Key>
      <Parameter>currentCredId</Parameter>
    </Key>
  </Get>
</KeyValueMapOperations>

After this executes, the context variable currentCredId holds "ABC123". Then there is a second KVM policy like this:

<KeyValueMapOperations name='KVM-GetCred' mapIdentifier='map1'>
  <Scope>environment</Scope>
  <ExpiryTimeInSecs>300</ExpiryTimeInSecs>
  <Get assignTo='cred'>
    <Key>
      <Parameter>cred</Parameter>
      <Parameter ref='currentCredId'/>
    </Key>
  </Get>
</KeyValueMapOperations>
<br>

After this policy executes, "cred" holds the Json {"any" : "json", "here" : true }

At time T1, you update the KVM store (via the mgmt API or UI) to be

key value
currentCredId DEF789
cred__ABC123 {"any" : "json", "here" : true }
cred__DEF780 {"any" : "different json", "here" : true }

Notice the currentCredId has been updated. And as you know, the KVM policies continue to retrieve the value in their hot cache, which is ABC123. At some point at time T2, the entries in that hot cache expire and the policies begin to read the new data. At which point currentCredId will hold DEF789 and the cred variable will hold {"any" : "different json", "here" : true }

There is no need for any "error". Your APIs will just get updated data when they get updated data.

Thanks again @Dino-at-Google for the complete details.

That clarifies - no matter what, the updated value will be available only after the TTL expiry if the KVM fetch is cached.

I have another thought based on your idea

key value
currentCredId

ABC123


updatedCredId

DEF789


<KeyValueMapOperations name='KVM-GetCurrent' mapIdentifier='map1'>
<Scope>environment</Scope>
<ExpiryTimeInSecs>300</ExpiryTimeInSecs>
<Get assignTo='currentCredId' >
<Key>
<Parameter>currentCredId</Parameter>
</Key>
</Get>
</KeyValueMapOperations>
<KeyValueMapOperations name='KVM-GetCurrent' mapIdentifier='map1'>
<Scope>environment</Scope>
<ExpiryTimeInSecs>300</ExpiryTimeInSecs>
<Get assignTo='updatedCredId'> <Key> <Parameter>updatedCredId</Parameter> </Key> </Get> </KeyValueMapOperations>

Have a condition like

updatedCredId != currentCredId, use updatedCredId as the value

Do a delete of the entry in the proxy if

updatedCredId == currentCredId (this will happen after TTL expiry)

<KeyValueMapOperations name='KVM-GetCurrent' mapIdentifier='map1'>
<Scope>environment</Scope>   
<Delete>
<Key>
<Parameter>updatedCredId</Parameter>
</Key>
</Delete>
</KeyValueMapOperations>

Pls let me know your thoughts on this.