cache the "tree"

This commit is contained in:
Athou
2013-07-02 18:07:08 +02:00
parent 18016c952e
commit f0f1a7f87b
15 changed files with 216 additions and 76 deletions

View File

@@ -6,6 +6,8 @@ import org.apache.commons.codec.digest.DigestUtils;
import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.FeedEntry;
import com.commafeed.backend.model.User;
import com.commafeed.frontend.model.Category;
public abstract class CacheService {
@@ -13,9 +15,15 @@ public abstract class CacheService {
public abstract void setLastEntries(Feed feed, List<String> entries);
public String buildKey(Feed feed, FeedEntry entry) {
public String buildUniqueEntryKey(Feed feed, FeedEntry entry) {
return DigestUtils.sha1Hex(entry.getGuid() +
entry.getUrl());
}
public abstract Category getRootCategory(User user);
public abstract void setRootCategory(User user, Category category);
public abstract void invalidateRootCategory(User... users);
}

View File

@@ -1,46 +0,0 @@
package com.commafeed.backend.cache;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Alternative;
import javax.inject.Inject;
import com.commafeed.backend.model.Feed;
import com.commafeed.backend.services.ApplicationSettingsService;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
@Alternative
@ApplicationScoped
public class InMemoryCacheService extends CacheService {
@Inject
ApplicationSettingsService applicationSettingsService;
private Cache<Long, List<String>> entryCache;
@PostConstruct
private void init() {
int capacity = applicationSettingsService.get().isHeavyLoad() ? 1000000 : 100;
entryCache = CacheBuilder.newBuilder()
.maximumSize(capacity).expireAfterWrite(24, TimeUnit.HOURS).build();
}
@Override
public List<String> getLastEntries(Feed feed) {
List<String> list = entryCache.getIfPresent(feed.getId());
if (list == null) {
list = Collections.emptyList();
}
return list;
}
@Override
public void setLastEntries(Feed feed, List<String> entries) {
entryCache.put(feed.getId(), entries);
}
}

View File

@@ -0,0 +1,40 @@
package com.commafeed.backend.cache;
import java.util.Collections;
import java.util.List;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Alternative;
import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.User;
import com.commafeed.frontend.model.Category;
@Alternative
@ApplicationScoped
public class NoopCacheService extends CacheService {
@Override
public List<String> getLastEntries(Feed feed) {
return Collections.emptyList();
}
@Override
public void setLastEntries(Feed feed, List<String> entries) {
}
@Override
public Category getRootCategory(User user) {
return null;
}
@Override
public void setRootCategory(User user, Category category) {
}
@Override
public void invalidateRootCategory(User... users) {
}
}

View File

@@ -7,26 +7,37 @@ import java.util.concurrent.TimeUnit;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Alternative;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Pipeline;
import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.Models;
import com.commafeed.backend.model.User;
import com.commafeed.frontend.model.Category;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.api.client.util.Lists;
@Alternative
@ApplicationScoped
public class RedisCacheService extends CacheService {
private static final Logger log = LoggerFactory.getLogger(RedisCacheService.class);
private JedisPool pool = new JedisPool(new JedisPoolConfig(), "localhost");
private ObjectMapper mapper = new ObjectMapper();
@Override
public List<String> getLastEntries(Feed feed) {
List<String> list = Lists.newArrayList();
Jedis jedis = pool.getResource();
try {
String key = buildKey(feed);
String key = buildRedisEntryKey(feed);
Set<String> members = jedis.smembers(key);
for (String member : members) {
list.add(member);
@@ -41,7 +52,7 @@ public class RedisCacheService extends CacheService {
public void setLastEntries(Feed feed, List<String> entries) {
Jedis jedis = pool.getResource();
try {
String key = buildKey(feed);
String key = buildRedisEntryKey(feed);
Pipeline pipe = jedis.pipelined();
pipe.del(key);
@@ -55,7 +66,64 @@ public class RedisCacheService extends CacheService {
}
}
private String buildKey(Feed feed) {
@Override
public Category getRootCategory(User user) {
Category cat = null;
Jedis jedis = pool.getResource();
try {
String key = buildRedisRootCategoryKey(user);
String json = jedis.get(key);
if (json != null) {
cat = mapper.readValue(json, Category.class);
}
} catch (Exception e) {
log.error(e.getMessage(), e);
} finally {
pool.returnResource(jedis);
}
return cat;
}
@Override
public void setRootCategory(User user, Category category) {
Jedis jedis = pool.getResource();
try {
String key = buildRedisRootCategoryKey(user);
Pipeline pipe = jedis.pipelined();
pipe.del(key);
pipe.set(key, mapper.writeValueAsString(category));
pipe.expire(key, (int) TimeUnit.MINUTES.toSeconds(30));
pipe.sync();
} catch (JsonProcessingException e) {
log.error(e.getMessage(), e);
} finally {
pool.returnResource(jedis);
}
}
@Override
public void invalidateRootCategory(User... users) {
Jedis jedis = pool.getResource();
try {
Pipeline pipe = jedis.pipelined();
if (users != null) {
for (User user : users) {
String key = buildRedisRootCategoryKey(user);
pipe.del(key);
}
}
pipe.sync();
} finally {
pool.returnResource(jedis);
}
}
private String buildRedisRootCategoryKey(User user) {
return "root_cat:" + Models.getId(user);
}
private String buildRedisEntryKey(Feed feed) {
return "feed:" + feed.getId();
}