Applix Systems
Applix Systems

Reputation: 1

Maintaining reference to already-loaded cache between server restarts, or, after a new version of the app is deployed

So I have an app deployed in appengine and it uses JCache as the cache API. Fact 1: The cache is loaded with data from the DB every day between 00:01 am and 00:04 am. This process works and there is no issue with this. Fact 2: I use "dedicated" cache (as against shared cache). Fact 3: I have chosen auto-scaling with min-instances: 0 and max-instances: 1, thereby implying that "start an instance when a user makes a request" and "shut that instance down after 'N' minutes of inactivity", where N is approximately 15 minutes.

Scenario 1:

Scenario 2:

Question: How can one hold reference to the actual cache object between when an instance going down and another instance comes up?

Here is the relevant code for the above:

appengine-web.xml file:

    <automatic-scaling>
        <min-idle-instances>0</min-idle-instances>
        <max-idle-instances>0</max-idle-instances>
        <min-instances>0</min-instances>
        <max-instances>1</max-instances>
    </automatic-scaling>

this is how the cache is loaded every night (this code is in CacheController)...

    Calendar            calnExpr            =   null;
    List<EstbStaffAsst> listOfEstbStaffAsst =   null;

    calnExpr    =   Calendar.getInstance(TimeZone.getTimeZone(CacheController.getEstbTZFromCache()));
    calnExpr.set(Calendar.HOUR_OF_DAY, 23);
    calnExpr.set(Calendar.MINUTE, 59);
    calnExpr.set(Calendar.SECOND, 59);
    calnExpr.set(Calendar.MILLISECOND, 999);
    mapProperties.put(GCacheFactory.EXPIRATION, new Date(calnExpr.getTimeInMillis()));
    try {
        cacheStffAsst   =   CacheController.getCacheStffAsst();
        if  ((null == cacheStffAsst) || (cacheStffAsst.isEmpty()))  {
            cacheStffAsst   =   cacheFactory.createCache(mapProperties);
        }
        listOfEstbStaffAsst =   EstbStffAsst.getList();
        if(null != listOfEstbStaffAsst && !(listOfEstbStaffAsst.isEmpty()) && listOfEstbStaffAsst.size() > 0)   {
            cacheStffAsst.put("estbStaffAsst", listOfEstbStaffAsst);
            cacheManager.registerCache("estbStaffAsst", cacheStffAsst);
        }
    }
    catch(Exception e)  {
    }

and this is how an attempt (in vain) is made in the static block of CacheController to see if the cache exists (alas it does not after every instance bounce)....

cacheManager    =   CacheManager.getInstance();
cacheStffAsst   =   cacheManager.getCache("estbStaffAsst");

Solution 1: configure auto-scaling as min-instances: 1 and max-instance: 1 so 1 instance is always running. But this is expensive.

Solution 2: configure auto-scaling as min-instances: 0 and max-instance: 1 and keep pinging this instance with a "keep-alive" http post every 10 minutes. This, I believe, is a brute force method of achieving the same result as Solution 1 above. So it too is expensive.

Solution 3: Write start up and shutdown hooks and listen for messages on these hooks. Upon receiving a "shut(ing) down" msg, serialize the class that holds references to the cache (in this case the CacheController) and store the serialized blob on, say, Cloud Storage. Upon receiving the "start(ing) up" message, read the serialized blob from cloud storage, reconstruct the app object that holds reference to the cache

I have tried (1) and (2) above and discarded them because they are expensive. I have not tried Solution 3. But before I do, I wanted to know if it is normal to build cache upon every instance startup?

If it is normal, then, isn't the whole purpose of the cache lost because every time an instance is bounced and the cache has to be reloaded, significant I/O costs are incurred.

If it is not normal, then, is there a better way to hold references to the cache between instance shutdown and startup?

Upvotes: 0

Views: 31

Answers (0)

Related Questions