views:

361

answers:

3

I am using jsr107 JCache in Google Apps Engine to save website data. My code looks like:

    public static String read(String link, boolean UTF8) throws Exception {

    URL url = new URL(link);

    String cached = CacheLogic.instance().get(link);

    if (!StringUtil.isEmpty(cached)) {
     return cached;
    }

    // Here i save the website's context into data

    CacheLogic.instance().put(link, data);

    return data;

    }

My CacheLogic:

public class CacheLogic {

 private static CacheLogic singleton;
 private Cache cache;
 private final int TTL = 60;

 public static CacheLogic instance() {

  if (singleton == null) {
   singleton = new CacheLogic();
  }

  return singleton;

 }

 private CacheLogic() {

  Map<String, Integer> props = new HashMap<String, Integer>();
  props.put(GCacheFactory.EXPIRATION_DELTA, TTL);

  try {
   CacheFactory cacheFactory = CacheManager.getInstance().getCacheFactory();
   cache = cacheFactory.createCache(props);
  } catch (CacheException e) {
   e.printStackTrace();
  }

 }

 public void put(String key, String value) {
  cache.remove(key);
  cache.put(key, value);
  CacheStatistics stats = cache.getCacheStatistics();
  System.out.println("[CacheLogic] New entry added. Count=" + stats.getObjectCount());
  System.out.println("[CacheLogic] New entry added. size=" + cache.size());
 }

 public String get(String key) {
  return (String) cache.get(key);
 }

}

I have set the cache expire time to 60 seconds and I call read with arguments like 'http://www.google.com/something' or 'http://stackoverflow.com/something'.

Heres the thing.

If call read the read method with the same arguments all the time within the 60 seconds i first called it, I always get the cached data. Perfect.

However, once it has gone 60+ seconds, I get null back. I read the website's and put it into the cache. Next time i call it, I get null again.

It seems like the memcache never saves the data after the expire time has ended, no matter the key.

Have i used the API in a incorrect way?

UPDATE 1: I have only tried this locally.

+3  A: 

Recently read a post (can't find it now) that using JCache GCacheFactory.EXPIRATION_DELTA expires the entire cache and you must use the Low-level API to expire individual objects.

Chris
I found a link supporting that theory: http://javathings.blogspot.com/2009/07/cache-expiration-in-google-app-engine.html
Fedearne
A: 

Added bounty for practical examples for doing this.

corgrath
A: 

Here is a practical example...

public class CacheLogic {

 private static CacheLogic singleton;
 private Cache cache;
 //private final int TTL = 60;

 public static CacheLogic instance() {

  if (singleton == null) {
   singleton = new CacheLogic();
  }

  return singleton;

 }

 private CacheLogic() {

  //Map<String, Integer> props = new HashMap<String, Integer>();
  //props.put(GCacheFactory.EXPIRATION_DELTA, TTL);

  try {
   CacheFactory cacheFactory = CacheManager.getInstance().getCacheFactory();
   cache = cacheFactory.createCache(/*props*/);
  } catch (CacheException e) {
   e.printStackTrace();
  }

 }

 public void put(String key, String value) {
  cache.remove(key);
  cache.put(key, value);
  CacheStatistics stats = cache.getCacheStatistics();
  System.out.println("[CacheLogic] New entry added. Count=" + stats.getObjectCount());
  System.out.println("[CacheLogic] New entry added. size=" + cache.size());
 }

 public String get(String key) {
  return (String) cache.get(key);
 }

}

By default, objects stored in the cache will remain in the cache for "as long as possible". You are setting objects saved in the cache to be deleted after 60 seconds, and yet it seems to surprise you that objects are unavailable after 60 seconds.....

Finbarr