package org.togglz.appengine.repository;
import org.togglz.core.Feature;
import org.togglz.core.repository.FeatureState;
import org.togglz.core.repository.StateRepository;
import com.google.appengine.api.memcache.Expiration;
import com.google.appengine.api.memcache.MemcacheService;
import com.google.appengine.api.memcache.MemcacheServiceFactory;
import java.io.Serializable;
/**
* Decorates a given StateRepository adding caching capabilities. Leverages GAE's MemcacheServices. Default expiration time is
* 3600 seconds.
*
* @author Fábio Franco Uechi
*/
public class MemcacheStateRepository implements StateRepository {
private StateRepository delegate;
private MemcacheService cache = MemcacheServiceFactory.getMemcacheService();
private Expiration expiration = Expiration.byDeltaSeconds(3600);
private static final String KEY_PREFIX = MemcacheStateRepository.class.getName();
public MemcacheStateRepository(StateRepository delegate) {
this.delegate = delegate;
}
public MemcacheStateRepository(StateRepository delegate, int ttlInSeconds) {
this(delegate);
this.expiration = Expiration.byDeltaMillis(ttlInSeconds);
}
@Override
public FeatureState getFeatureState(Feature feature) {
// first try to find it from the cache
CacheEntry entry = (CacheEntry) cache.get(key(feature.name()));
if (entry != null) {
return entry.getState() != null ? entry.getState() : null;
}
// no cache hit
FeatureState featureState = delegate.getFeatureState(feature);
// cache the result (may be null)
cache.put(key(feature.name()), new CacheEntry(featureState != null ? featureState : null), getExpiration());
// return the result
return featureState;
}
String key(String featureName) {
return KEY_PREFIX + featureName;
}
private Expiration getExpiration() {
return this.expiration;
}
@Override
public void setFeatureState(FeatureState featureState) {
delegate.setFeatureState(featureState);
cache.delete(key(featureState.getFeature().name()));
}
/**
* This class represents a cached repository lookup
*/
private static class CacheEntry implements Serializable {
private final FeatureState state;
public CacheEntry(FeatureState state) {
this.state = state;
}
public FeatureState getState() {
return state;
}
}
}