From f0f1a7f87b29cb2195e3d38cfb1ed0b45fd0d777 Mon Sep 17 00:00:00 2001 From: Athou Date: Tue, 2 Jul 2013 18:07:08 +0200 Subject: [PATCH] cache the "tree" --- pom.xml | 2 +- .../commafeed/backend/cache/CacheService.java | 10 ++- .../backend/cache/InMemoryCacheService.java | 46 ------------ .../backend/cache/NoopCacheService.java | 40 ++++++++++ .../backend/cache/RedisCacheService.java | 74 ++++++++++++++++++- .../backend/dao/FeedEntryStatusDAO.java | 6 +- .../backend/dao/FeedSubscriptionDAO.java | 7 +- .../backend/feeds/FeedRefreshUpdater.java | 2 +- .../commafeed/backend/feeds/OPMLImporter.java | 7 +- .../com/commafeed/backend/model/Models.java | 29 ++++++++ .../backend/services/FeedUpdateService.java | 9 +++ .../frontend/rest/resources/CategoryREST.java | 38 ++++++---- .../frontend/rest/resources/EntryREST.java | 6 +- .../frontend/rest/resources/FeedREST.java | 11 ++- .../frontend/rest/resources/UserREST.java | 5 ++ 15 files changed, 216 insertions(+), 76 deletions(-) delete mode 100644 src/main/java/com/commafeed/backend/cache/InMemoryCacheService.java create mode 100644 src/main/java/com/commafeed/backend/cache/NoopCacheService.java create mode 100644 src/main/java/com/commafeed/backend/model/Models.java diff --git a/pom.xml b/pom.xml index 55188950..0fb4a468 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ java:openejb/Resource/My DataSource org.hibernate.dialect.HSQLDialect false - com.commafeed.backend.cache.InMemoryCacheService + com.commafeed.backend.cache.NoopCacheService diff --git a/src/main/java/com/commafeed/backend/cache/CacheService.java b/src/main/java/com/commafeed/backend/cache/CacheService.java index aa1dc339..401c964a 100644 --- a/src/main/java/com/commafeed/backend/cache/CacheService.java +++ b/src/main/java/com/commafeed/backend/cache/CacheService.java @@ -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 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); + } diff --git a/src/main/java/com/commafeed/backend/cache/InMemoryCacheService.java b/src/main/java/com/commafeed/backend/cache/InMemoryCacheService.java deleted file mode 100644 index a59dba3d..00000000 --- a/src/main/java/com/commafeed/backend/cache/InMemoryCacheService.java +++ /dev/null @@ -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> 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 getLastEntries(Feed feed) { - List list = entryCache.getIfPresent(feed.getId()); - if (list == null) { - list = Collections.emptyList(); - } - return list; - } - - @Override - public void setLastEntries(Feed feed, List entries) { - entryCache.put(feed.getId(), entries); - } -} diff --git a/src/main/java/com/commafeed/backend/cache/NoopCacheService.java b/src/main/java/com/commafeed/backend/cache/NoopCacheService.java new file mode 100644 index 00000000..3197132a --- /dev/null +++ b/src/main/java/com/commafeed/backend/cache/NoopCacheService.java @@ -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 getLastEntries(Feed feed) { + return Collections.emptyList(); + } + + @Override + public void setLastEntries(Feed feed, List entries) { + } + + @Override + public Category getRootCategory(User user) { + return null; + } + + @Override + public void setRootCategory(User user, Category category) { + + } + + @Override + public void invalidateRootCategory(User... users) { + + } +} diff --git a/src/main/java/com/commafeed/backend/cache/RedisCacheService.java b/src/main/java/com/commafeed/backend/cache/RedisCacheService.java index 9c68c1de..d3cd5d8f 100644 --- a/src/main/java/com/commafeed/backend/cache/RedisCacheService.java +++ b/src/main/java/com/commafeed/backend/cache/RedisCacheService.java @@ -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 getLastEntries(Feed feed) { List list = Lists.newArrayList(); Jedis jedis = pool.getResource(); try { - String key = buildKey(feed); + String key = buildRedisEntryKey(feed); Set 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 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(); } diff --git a/src/main/java/com/commafeed/backend/dao/FeedEntryStatusDAO.java b/src/main/java/com/commafeed/backend/dao/FeedEntryStatusDAO.java index 953f30b7..14efb91a 100644 --- a/src/main/java/com/commafeed/backend/dao/FeedEntryStatusDAO.java +++ b/src/main/java/com/commafeed/backend/dao/FeedEntryStatusDAO.java @@ -20,7 +20,6 @@ import javax.persistence.criteria.SetJoin; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; -import org.hibernate.Hibernate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,6 +34,7 @@ import com.commafeed.backend.model.FeedEntry_; import com.commafeed.backend.model.FeedSubscription; import com.commafeed.backend.model.FeedSubscription_; import com.commafeed.backend.model.Feed_; +import com.commafeed.backend.model.Models; import com.commafeed.backend.model.User; import com.commafeed.backend.model.UserSettings.ReadingOrder; import com.commafeed.backend.services.ApplicationSettingsService; @@ -507,8 +507,8 @@ public class FeedEntryStatusDAO extends GenericDAO { List results) { if (includeContent) { for (FeedEntryStatus status : results) { - Hibernate.initialize(status.getSubscription().getFeed()); - Hibernate.initialize(status.getEntry().getContent()); + Models.initialize(status.getSubscription().getFeed()); + Models.initialize(status.getEntry().getContent()); } } return results; diff --git a/src/main/java/com/commafeed/backend/dao/FeedSubscriptionDAO.java b/src/main/java/com/commafeed/backend/dao/FeedSubscriptionDAO.java index 23392180..f56695c7 100644 --- a/src/main/java/com/commafeed/backend/dao/FeedSubscriptionDAO.java +++ b/src/main/java/com/commafeed/backend/dao/FeedSubscriptionDAO.java @@ -8,14 +8,13 @@ import javax.persistence.criteria.JoinType; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; -import org.hibernate.Hibernate; - import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.FeedCategory; import com.commafeed.backend.model.FeedCategory_; import com.commafeed.backend.model.FeedSubscription; import com.commafeed.backend.model.FeedSubscription_; import com.commafeed.backend.model.Feed_; +import com.commafeed.backend.model.Models; import com.commafeed.backend.model.User; import com.commafeed.backend.model.User_; import com.google.common.collect.Iterables; @@ -127,8 +126,8 @@ public class FeedSubscriptionDAO extends GenericDAO { private void initRelations(FeedSubscription sub) { if (sub != null) { - Hibernate.initialize(sub.getFeed()); - Hibernate.initialize(sub.getCategory()); + Models.initialize(sub.getFeed()); + Models.initialize(sub.getCategory()); } } } diff --git a/src/main/java/com/commafeed/backend/feeds/FeedRefreshUpdater.java b/src/main/java/com/commafeed/backend/feeds/FeedRefreshUpdater.java index 4c282ec5..0794d308 100644 --- a/src/main/java/com/commafeed/backend/feeds/FeedRefreshUpdater.java +++ b/src/main/java/com/commafeed/backend/feeds/FeedRefreshUpdater.java @@ -106,7 +106,7 @@ public class FeedRefreshUpdater { List subscriptions = null; for (FeedEntry entry : entries) { - String cacheKey = cache.buildKey(feed, entry); + String cacheKey = cache.buildUniqueEntryKey(feed, entry); if (!lastEntries.contains(cacheKey)) { log.debug("cache miss for {}", entry.getUrl()); if (subscriptions == null) { diff --git a/src/main/java/com/commafeed/backend/feeds/OPMLImporter.java b/src/main/java/com/commafeed/backend/feeds/OPMLImporter.java index e62691f9..6857a539 100644 --- a/src/main/java/com/commafeed/backend/feeds/OPMLImporter.java +++ b/src/main/java/com/commafeed/backend/feeds/OPMLImporter.java @@ -13,6 +13,7 @@ import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.commafeed.backend.cache.CacheService; import com.commafeed.backend.dao.FeedCategoryDAO; import com.commafeed.backend.model.FeedCategory; import com.commafeed.backend.model.User; @@ -34,6 +35,9 @@ public class OPMLImporter { @Inject FeedCategoryDAO feedCategoryDAO; + @Inject + CacheService cache; + @SuppressWarnings("unchecked") @Asynchronous public void importOpml(User user, String xml) { @@ -77,16 +81,17 @@ public class OPMLImporter { if (StringUtils.isBlank(title)) { title = "Unnamed subscription"; } - // make sure we continue with the import process even a feed failed try { feedSubscriptionService.subscribe(user, outline.getXmlUrl(), title, parent); + } catch (FeedSubscriptionException e) { throw e; } catch (Exception e) { log.error("error while importing {}: {}", outline.getXmlUrl(), e.getMessage()); } } + cache.invalidateRootCategory(user); } } diff --git a/src/main/java/com/commafeed/backend/model/Models.java b/src/main/java/com/commafeed/backend/model/Models.java new file mode 100644 index 00000000..dbdecc67 --- /dev/null +++ b/src/main/java/com/commafeed/backend/model/Models.java @@ -0,0 +1,29 @@ +package com.commafeed.backend.model; + +import org.hibernate.Hibernate; +import org.hibernate.HibernateException; +import org.hibernate.proxy.HibernateProxy; +import org.hibernate.proxy.LazyInitializer; + +public class Models { + + /** + * initialize a proxy + */ + public static void initialize(Object proxy) throws HibernateException { + Hibernate.initialize(proxy); + } + + /** + * extract the id from the proxy without initializing it + */ + public static Long getId(AbstractModel model) { + if (model instanceof HibernateProxy) { + LazyInitializer lazyInitializer = ((HibernateProxy) model).getHibernateLazyInitializer(); + if (lazyInitializer.isUninitialized()) { + return (Long) lazyInitializer.getIdentifier(); + } + } + return model.getId(); + } +} diff --git a/src/main/java/com/commafeed/backend/services/FeedUpdateService.java b/src/main/java/com/commafeed/backend/services/FeedUpdateService.java index 9a8a8a54..89c728b8 100644 --- a/src/main/java/com/commafeed/backend/services/FeedUpdateService.java +++ b/src/main/java/com/commafeed/backend/services/FeedUpdateService.java @@ -7,6 +7,7 @@ import javax.ejb.Stateless; import javax.inject.Inject; import com.commafeed.backend.MetricsBean; +import com.commafeed.backend.cache.CacheService; import com.commafeed.backend.dao.FeedEntryDAO; import com.commafeed.backend.dao.FeedEntryDAO.EntryWithFeed; import com.commafeed.backend.dao.FeedEntryStatusDAO; @@ -17,6 +18,7 @@ import com.commafeed.backend.model.FeedEntry; import com.commafeed.backend.model.FeedEntryContent; import com.commafeed.backend.model.FeedEntryStatus; import com.commafeed.backend.model.FeedSubscription; +import com.commafeed.backend.model.User; import com.google.common.collect.Lists; @Stateless @@ -34,6 +36,9 @@ public class FeedUpdateService { @Inject MetricsBean metricsBean; + @Inject + CacheService cache; + public void updateEntry(Feed feed, FeedEntry entry, List subscriptions) { @@ -61,12 +66,16 @@ public class FeedUpdateService { if (update != null) { List statusUpdateList = Lists.newArrayList(); + List users = Lists.newArrayList(); for (FeedSubscription sub : subscriptions) { FeedEntryStatus status = new FeedEntryStatus(); status.setEntry(update); status.setSubscription(sub); statusUpdateList.add(status); + + users.add(sub.getUser()); } + cache.invalidateRootCategory(users.toArray(new User[0])); feedEntryDAO.saveOrUpdate(update); feedEntryStatusDAO.saveOrUpdate(statusUpdateList); metricsBean.entryUpdated(statusUpdateList.size()); diff --git a/src/main/java/com/commafeed/frontend/rest/resources/CategoryREST.java b/src/main/java/com/commafeed/frontend/rest/resources/CategoryREST.java index 434ee7f9..59c963f7 100644 --- a/src/main/java/com/commafeed/frontend/rest/resources/CategoryREST.java +++ b/src/main/java/com/commafeed/frontend/rest/resources/CategoryREST.java @@ -23,12 +23,14 @@ import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.commafeed.backend.cache.CacheService; import com.commafeed.backend.dao.FeedCategoryDAO; import com.commafeed.backend.dao.FeedEntryStatusDAO; import com.commafeed.backend.dao.FeedSubscriptionDAO; import com.commafeed.backend.model.FeedCategory; import com.commafeed.backend.model.FeedEntryStatus; import com.commafeed.backend.model.FeedSubscription; +import com.commafeed.backend.model.User; import com.commafeed.backend.model.UserRole.Role; import com.commafeed.backend.model.UserSettings.ReadingOrder; import com.commafeed.frontend.SecurityCheck; @@ -71,6 +73,9 @@ public class CategoryREST extends AbstractResourceREST { @Inject FeedSubscriptionDAO feedSubscriptionDAO; + @Inject + CacheService cache; + @Path("/entries") @GET @ApiOperation(value = "Get category entries", notes = "Get a list of category entries", responseClass = "com.commafeed.frontend.model.Entries") @@ -226,7 +231,7 @@ public class CategoryREST extends AbstractResourceREST { feedEntryStatusDAO.markCategoryEntries(getUser(), categories, olderThan); } - + cache.invalidateRootCategory(getUser()); return Response.ok(Status.OK).build(); } @@ -249,6 +254,7 @@ public class CategoryREST extends AbstractResourceREST { cat.setParent(parent); } feedCategoryDAO.saveOrUpdate(cat); + cache.invalidateRootCategory(getUser()); return Response.ok().build(); } @@ -279,6 +285,7 @@ public class CategoryREST extends AbstractResourceREST { feedCategoryDAO.saveOrUpdate(categories); feedCategoryDAO.delete(cat); + cache.invalidateRootCategory(getUser()); return Response.ok().build(); } else { return Response.status(Status.NOT_FOUND).build(); @@ -343,7 +350,7 @@ public class CategoryREST extends AbstractResourceREST { } feedCategoryDAO.saveOrUpdate(category); - + cache.invalidateRootCategory(getUser()); return Response.ok(Status.OK).build(); } @@ -361,7 +368,7 @@ public class CategoryREST extends AbstractResourceREST { } category.setCollapsed(req.isCollapse()); feedCategoryDAO.saveOrUpdate(category); - + cache.invalidateRootCategory(getUser()); return Response.ok(Status.OK).build(); } @@ -382,18 +389,23 @@ public class CategoryREST extends AbstractResourceREST { @Path("/get") @ApiOperation(value = "Get feed categories", notes = "Get all categories and subscriptions of the user", responseClass = "com.commafeed.frontend.model.Category") public Response getSubscriptions() { + User user = getUser(); - List categories = feedCategoryDAO.findAll(getUser()); - List subscriptions = feedSubscriptionDAO - .findAll(getUser()); - Map unreadCount = feedEntryStatusDAO - .getUnreadCount(getUser()); - - Category root = buildCategory(null, categories, subscriptions, - unreadCount); - root.setId("all"); - root.setName("All"); + Category root = cache.getRootCategory(user); + if (root == null) { + log.debug("root category cache miss for {}", user.getName()); + List categories = feedCategoryDAO.findAll(user); + List subscriptions = feedSubscriptionDAO + .findAll(getUser()); + Map unreadCount = feedEntryStatusDAO + .getUnreadCount(getUser()); + root = buildCategory(null, categories, subscriptions, + unreadCount); + root.setId("all"); + root.setName("All"); + cache.setRootCategory(user, root); + } return Response.ok(root).build(); } diff --git a/src/main/java/com/commafeed/frontend/rest/resources/EntryREST.java b/src/main/java/com/commafeed/frontend/rest/resources/EntryREST.java index 686c914d..bf07a76e 100644 --- a/src/main/java/com/commafeed/frontend/rest/resources/EntryREST.java +++ b/src/main/java/com/commafeed/frontend/rest/resources/EntryREST.java @@ -13,6 +13,7 @@ import javax.ws.rs.core.Response.Status; import org.apache.commons.lang.StringUtils; +import com.commafeed.backend.cache.CacheService; import com.commafeed.backend.dao.FeedEntryStatusDAO; import com.commafeed.backend.model.FeedEntryStatus; import com.commafeed.backend.services.FeedEntryService; @@ -36,6 +37,9 @@ public class EntryREST extends AbstractResourceREST { @Inject FeedEntryStatusDAO feedEntryStatusDAO; + @Inject + CacheService cache; + @Path("/mark") @POST @ApiOperation(value = "Mark a feed entry", notes = "Mark a feed entry as read/unread") @@ -47,7 +51,7 @@ public class EntryREST extends AbstractResourceREST { feedEntryService.markEntry(getUser(), Long.valueOf(req.getId()), req.getFeedId(), req.isRead()); - + cache.invalidateRootCategory(getUser()); return Response.ok(Status.OK).build(); } diff --git a/src/main/java/com/commafeed/frontend/rest/resources/FeedREST.java b/src/main/java/com/commafeed/frontend/rest/resources/FeedREST.java index f4635b45..ac9ccd2f 100644 --- a/src/main/java/com/commafeed/frontend/rest/resources/FeedREST.java +++ b/src/main/java/com/commafeed/frontend/rest/resources/FeedREST.java @@ -37,6 +37,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.commafeed.backend.StartupBean; +import com.commafeed.backend.cache.CacheService; import com.commafeed.backend.dao.FeedCategoryDAO; import com.commafeed.backend.dao.FeedEntryStatusDAO; import com.commafeed.backend.dao.FeedSubscriptionDAO; @@ -112,6 +113,9 @@ public class FeedREST extends AbstractResourceREST { @Inject OPMLExporter opmlExporter; + @Inject + CacheService cache; + @Context private HttpServletRequest request; @@ -288,7 +292,7 @@ public class FeedREST extends AbstractResourceREST { if (subscription != null) { feedEntryStatusDAO.markSubscriptionEntries(subscription, olderThan); } - + cache.invalidateRootCategory(getUser()); return Response.ok(Status.OK).build(); } @@ -375,6 +379,7 @@ public class FeedREST extends AbstractResourceREST { .entity("Failed to subscribe to URL " + url + ": " + e.getMessage()).build(); } + cache.invalidateRootCategory(getUser()); return Response.ok(Status.OK).build(); } @@ -419,6 +424,7 @@ public class FeedREST extends AbstractResourceREST { req.getId()); if (sub != null) { feedSubscriptionDAO.delete(sub); + cache.invalidateRootCategory(getUser()); return Response.ok(Status.OK).build(); } else { return Response.status(Status.NOT_FOUND).build(); @@ -478,7 +484,7 @@ public class FeedREST extends AbstractResourceREST { } else { feedSubscriptionDAO.saveOrUpdate(subscription); } - + cache.invalidateRootCategory(getUser()); return Response.ok(Status.OK).build(); } @@ -517,6 +523,7 @@ public class FeedREST extends AbstractResourceREST { .status(Status.INTERNAL_SERVER_ERROR) .entity(e.getMessage()).build()); } + cache.invalidateRootCategory(getUser()); return Response.temporaryRedirect( URI.create(applicationSettingsService.get().getPublicUrl())) .build(); diff --git a/src/main/java/com/commafeed/frontend/rest/resources/UserREST.java b/src/main/java/com/commafeed/frontend/rest/resources/UserREST.java index ad7547df..a4c56519 100644 --- a/src/main/java/com/commafeed/frontend/rest/resources/UserREST.java +++ b/src/main/java/com/commafeed/frontend/rest/resources/UserREST.java @@ -12,6 +12,7 @@ import javax.ws.rs.core.Response.Status; import org.apache.commons.lang.StringUtils; import com.commafeed.backend.StartupBean; +import com.commafeed.backend.cache.CacheService; import com.commafeed.backend.dao.UserDAO; import com.commafeed.backend.dao.UserRoleDAO; import com.commafeed.backend.dao.UserSettingsDAO; @@ -56,6 +57,9 @@ public class UserREST extends AbstractResourceREST { @Inject PasswordEncryptionService encryptionService; + @Inject + CacheService cache; + @Path("/settings") @GET @ApiOperation(value = "Retrieve user settings", notes = "Retrieve user settings", responseClass = "com.commafeed.frontend.model.Settings") @@ -194,6 +198,7 @@ public class UserREST extends AbstractResourceREST { return Response.status(Status.FORBIDDEN).build(); } userService.unregister(getUser()); + cache.invalidateRootCategory(getUser()); return Response.ok().build(); } }