What is result caching?
Result caching offers the possibility to store the result returned for a given request for a limited period of time so that if a similar request is sent over this period of time the same result is sent without having to compute it.
What are the benefits/drawback of result caching?
Benefits:
- Faster responses.
- Reduces resources usage (CPU, network, database, ...)
- May reduce cost, if the API calls another API that is charged per call.
Brawbacks:
- Uses more memory.
- Accurency of the cached result may not be valid anymore.
- Only useful for functions that return information and does not perform actions.
How to implement result caching in a XINS API?
XINS provides classes in the org.xins.common.collections.expiry package which allow to cache object for a specified time.
/** * The collection that will keep the results. * The key of this map is a {@link Request} object and the value is a * {@link Result} object. */ private ExpiryFolder _functionCache; /** * Initializes the cache. */ public void initImpl(PropertiesReader properties) { // The strategy of the cache is keep the result for maximum 30 seconds with // a precision of 2 seconds. ExpiryStategy cacheStrategy = new ExpiryStrategy(30 * 1000, 2000); // Create the cache with this strategy _functionCache = new ExpiryFolder("MyFunction", cacheStrategy); } public Result call(Request request) throws Exception { // Directly return the result if available in the cache. Result cachedResult = (Result) _functionCache.find(request); if (cachedResult != null) { return cachedResult; } SuccessfulResult result = new SuccessfulResult(); // Fill the result object with data // Store the result in the cache before returning it _functionCache.put(request, result); return result; }
Advanced caching
- The ExpiryFolder class has 2 methods to find the result, find and get. If you call the get method, the cached object time will be reseted whereas the find method will no reset the time for the object. In our example, if the object is accessed once after 10 seconds, using the get method, the object will be stored 10 + 30 = 40 seconds in the cache, using the find method, it would have been stored 30 seconds.
- SuccessfulResult and UnsuccessfulResult may be stored, nevertheless it is advisable to only store the UnsuccessfulResult related to functional error codes.
- It is also possible to manage the cache from another function. To do this, the cache needs to be accessible for both function. The best way to do it, is to put the cache in a shared instance.
- It is recommended to have the cache time as a runtime property and have the precision to 10% of the cache time.