0

Over View of Application

I'm updating an existing tomcat web application to read certain resources from a REST API. Currently the application reads them from flat files. Since the application is very critical, I added a caching layer so that the objects returned by REST API are always available.

In the service layer of API client, if the request item is not found in the Cache, the request will be sent to the actual API, the response is put in MapDB cache and returned to caller. The startup listener calls a bunch of APIs with different parameters so that all data is now in MapDB cache. I do not set a expiration on the items in cache because I want them to always available unless I refresh on demand.

The problem is Web App and API client are different projects. Since API client decides to read from Cache or API, I'm not able to force refresh cache value from the application.

  • Should I add another parameter to function calls I make to API client or

    Object obj = ServiceFactory.getLanguageService()
                        .getLanguagesFromApi(env.getName(),
                                env.getEnvironmentType(),
                                env.getPhase().toString(), null, true);
    

The last "true" parameter indicates forcing cache refresh.

  • Should I get the existing value in cache to a temporary variable, delete the entry, make API call, if no value is returned because of some error, put the entry back into the cache.

            String key = ClientUtils.concatenateList(
                    Arrays.asList(ClientConstants.RESOURCE_LANGUAGE,
                            env.getName(), env.getEnvironmentType(),
                            env.getPhase(), null),
                    ClientConstants.CACHE_KEY_SEPERATOR,
                    ClientConstants.NULL_STRING);
    
            Object cachedElement = ClientCache.getCache().get(key);
            if (cachedElement != null) {
                ClientCache.getCache().delete(key);
            }
    
            Object obj = ServiceFactory.getLanguageService()
                    .getLanguagesFromApi(env.getName(),
                            env.getEnvironmentType(),
                            env.getPhase().toString(), null);
    
            if (obj == null) {
                ClientCache.getCache().put(key, cachedElement);
            }
    

What is the cleaner way to do this ? I feel adding parameters about caching to function makes it clumsy and add dependencies - like getUsers(String country, boolean forceAPIrequest). But deleting and adding same entries may also waste resources and heap space, causing GC over time. Also, App will directly access Client Cache to do these operations.

All this is based on strong assumption that our REST API is unreliable. Web App should not have any down time.

  • Can you add the ability to refresh the cache to the API client library, so that your webapp can use it as needed? Or are you concerned that the storage mechanism should be unknown to the webapp? – Mike Partridge Sep 15 '15 at 19:55
  • @MikePartridge, I want webapp to be unaware of the storage. Webapp simply makes a request and client returns it. However, webapp knows that caching can be enabled through a config file. Other apps that may use this client don't need caching and may not want to handle that. – TechCrunch Sep 15 '15 at 20:24
  • I decided to go ahead with adding extra parameter and write overloaded functions in client. Deleting and adding same object looks awful wastage of time and GC. However, I'm still open to suggestions. – TechCrunch Sep 16 '15 at 14:19
  • Doesn't adding the extra parameter make the webapp aware of the storage mechanism? – Mike Partridge Sep 16 '15 at 19:31
  • I'm writing overloaded methods in client with extra parameter of forAPIRequest for one of them. So that only cache aware apps can use that parameter. Rest of the apps don't care. Sounds ok ? – TechCrunch Sep 16 '15 at 19:42
1

If I understand correctly, caching is in place mainly for realiability in case of unavailability of REST service, not for performance.

In that case, you could call REST service every time you receive request from the client, if you get a response (REST service is working) you update the MapDB cache and return the response to API client. If REST service is down and you don't get the response, simply return cached value from MapDB.

This way your clients get always as up-to-date possible version as possible while keeping the reliability requirement.

You could include a flag in the response to your clients indicating whether the response is from cache or up-to-date. This might be useful for clients which absolutely require up-to-date response to the point that it is preferable to fail than to work with old data.

  • This is a good solution, except for I'm using caching for performance as well. The REST API does very heavy operations (query hundreds of databases) and the API is pretty much called on every page load of the web application. May be certain caching should be in the REST API as well. – TechCrunch Sep 16 '15 at 13:17
  • I want to avoid lot of network, each page load may call upto 3-5 REST APIs. – TechCrunch Sep 16 '15 at 13:28
0

Add a method to the API client refreshCache(...) that would refresh the entire cache, similar to what is done through your startup listener. If a cache-aware application using the API client knows that it needs refreshed data before asking for specific data, make it call refreshCache first.

  • Entire refresh may be too much, because it would kick at-least 12000 REST calls. I want to be able to refresh specific data. As I mentioned in other answer's comment, REST API does very heavy computations. – TechCrunch Sep 17 '15 at 17:14
-2

The call that you do first does s complete cache refresh yes? If do then why not schedule it.. If the full request comes back fine then flush and re instantiate the cache...

  • 1
    That is what I mentioned in my question. – TechCrunch Sep 15 '15 at 20:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.