How do you preheat a response cache in Edge?

Not applicable

For those resources that are cachable, especially when we have a high latency target system, how do we "preheat" the response cache?

0 4 434
4 REPLIES 4

It depends on your usecase and how caching is implemented in your proxy -

Lets take a simple case of a weather proxy - and lets say you use Response cache policy to cache weather response by zip code.

Easiest way to load entries to the cache is to actually send (load) requests to your API as your clients would make - it automatically populates the cache

From analytics standpoint, if you want to differentiate the actual traffic from the traffic that was used to 'warm' your cache - you could probably use a customer variable in your flow to do that

Alternatively, you could have dedicated flows to populate the cache -- these flows would use the same cache resource and keys -- so normal API calls , when it happens, would find the responses in the cache

Not applicable

+ Predictive caching ?

Load the response of other API calls assuming they will be called next when the first API call gets executed and if the quota.used = 0 so that you don't need to pre-populate using external triggers but depends on use case though .

Not applicable

We have implemented a fire and forget JSC policy for one of our customers that reads a list of URLs from KVM, calling these URLs results in populating the response cache. This Javascript callout is run on the back of a user authentication call and results in frequently accessed data being available from cache later in the user journey.

A couple notes about this implementation:

  1. It is crucial that you ensure that the callback not recurse or loop - this can result in exhaustion of MP resources very quickly bringing down the message processors. We achieve this by setting a header on the request and testing that this header is NOT present on the proxy request before executing the preheat cache callout.
  2. By running asynchronously you lose the ability to respond to errors - a robust logging framework on the endpoints you are calling will give you visibility when things don't go as planned.
  3. If you want to make your call as general as possible you will want to do some variable substitutions to ensure that the call back comes to the same org/environment.
  4. Give yourself the option of running the call in synchronous mode by including a query parameter. This will facilitate debugging while in develop mode. When making the sync call we also drop the response into a flow variable to aid in debugging.

Here is a sample of JSC code for realizing this:

var request,
    preheatSets = JSON.parse(context.getVariable("preheatConfig")),
    sync = context.getVariable("request.queryparam.sync");

preheatSets.forEach(function(set) {
    processSet(set, sync);
});


function processSet(set, sync) {
    if (set) {
        //now we want to do the variable substitutions
        var variables = getVariables(set.url);
        variables.forEach(function(variable) {
            var value = context.getVariable(variable);
            if (value)
                set.url = set.url.replace("{" + variable + "}", value);
        });

        //now do the same thing for each header
        var requestHeaders = {};

        set.headers.forEach(function(header) {
            var variables = getVariables(header.value);
            variables.forEach(function(variable) {
                var value = context.getVariable(variable);
                if (value)
                    header.value = header.value.replace("{" + variable + "}", value);
            });
            requestHeaders[header.name] = header.value;
        });

        requestHeaders["x-apigee-callback"] = "true";
        var myRequest = new Request(set.url, "GET", requestHeaders);
        // asynchronous GET for performance reasons
        var myResult = httpClient.send(myRequest);

        if (sync) {
            // Wait for the asynchronous GET request to finish
            myResult.waitForComplete();
            // get the response object from the exchange
            var response = myResult.getResponse();
            // get the HTTP status code from the response
            context.setVariable("preheatCache." + setName + "ResponseStatus", response.status);
        }
    }
}


function getVariables(str) {
    var ret = [],
        segments = str.split("{");
    segments.forEach(function(segment) {
        theVar = segment.split("}");
        if (theVar[0] && theVar.length > 1) ret.push(theVar[0]);
    });
    return ret;
}

Not applicable

Other clients have reused their JMeter tests as load generators and implemented a CRON job to periodically run scenarios to preheat caches.