From 43d7c16f66eb3b64d9dc9cc9ed104f7b275007c4 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Thu, 23 Aug 2018 14:38:41 +0300 Subject: [PATCH] Cache async relation queries. --- .../dao/relation/BaseRelationService.java | 58 ++++++++++++++++--- .../dao/service/BaseRelationServiceTest.java | 13 +++++ 2 files changed, 64 insertions(+), 7 deletions(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java index 9b89fe29f3..d88a1c4c42 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java @@ -16,9 +16,7 @@ package org.thingsboard.server.dao.relation; import com.google.common.base.Function; -import com.google.common.util.concurrent.AsyncFunction; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.*; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.Cache; @@ -272,8 +270,10 @@ public class BaseRelationService implements RelationService { @Cacheable(cacheNames = RELATIONS_CACHE, key = "{#from, #typeGroup}") @Override public List findByFrom(EntityId from, RelationTypeGroup typeGroup) { + validate(from); + validateTypeGroup(typeGroup); try { - return findByFromAsync(from, typeGroup).get(); + return relationDao.findAllByFrom(from, typeGroup).get(); } catch (InterruptedException | ExecutionException e) { throw new RuntimeException(e); } @@ -284,7 +284,28 @@ public class BaseRelationService implements RelationService { log.trace("Executing findByFrom [{}][{}]", from, typeGroup); validate(from); validateTypeGroup(typeGroup); - return relationDao.findAllByFrom(from, typeGroup); + + List fromAndTypeGroup = new ArrayList<>(); + fromAndTypeGroup.add(from); + fromAndTypeGroup.add(typeGroup); + + Cache cache = cacheManager.getCache(RELATIONS_CACHE); + List fromCache = cache.get(fromAndTypeGroup, List.class); + if (fromCache != null) { + return Futures.immediateFuture(fromCache); + } else { + ListenableFuture> relationsFuture = relationDao.findAllByFrom(from, typeGroup); + Futures.addCallback(relationsFuture, + new FutureCallback>() { + @Override + public void onSuccess(@Nullable List result) { + cache.putIfAbsent(fromAndTypeGroup, result); + } + @Override + public void onFailure(Throwable t) {} + }); + return relationsFuture; + } } @Override @@ -327,8 +348,10 @@ public class BaseRelationService implements RelationService { @Cacheable(cacheNames = RELATIONS_CACHE, key = "{#to, #typeGroup}") @Override public List findByTo(EntityId to, RelationTypeGroup typeGroup) { + validate(to); + validateTypeGroup(typeGroup); try { - return findByToAsync(to, typeGroup).get(); + return relationDao.findAllByTo(to, typeGroup).get(); } catch (InterruptedException | ExecutionException e) { throw new RuntimeException(e); } @@ -339,7 +362,28 @@ public class BaseRelationService implements RelationService { log.trace("Executing findByTo [{}][{}]", to, typeGroup); validate(to); validateTypeGroup(typeGroup); - return relationDao.findAllByTo(to, typeGroup); + + List toAndTypeGroup = new ArrayList<>(); + toAndTypeGroup.add(to); + toAndTypeGroup.add(typeGroup); + + Cache cache = cacheManager.getCache(RELATIONS_CACHE); + List fromCache = cache.get(toAndTypeGroup, List.class); + if (fromCache != null) { + return Futures.immediateFuture(fromCache); + } else { + ListenableFuture> relationsFuture = relationDao.findAllByTo(to, typeGroup); + Futures.addCallback(relationsFuture, + new FutureCallback>() { + @Override + public void onSuccess(@Nullable List result) { + cache.putIfAbsent(toAndTypeGroup, result); + } + @Override + public void onFailure(Throwable t) {} + }); + return relationsFuture; + } } @Override diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseRelationServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseRelationServiceTest.java index 743aefcc40..d269126d90 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseRelationServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseRelationServiceTest.java @@ -227,6 +227,13 @@ public abstract class BaseRelationServiceTest extends AbstractServiceTest { Assert.assertTrue(relations.contains(relationA)); Assert.assertTrue(relations.contains(relationB)); Assert.assertTrue(relations.contains(relationC)); + + //Test from cache + relations = relationService.findByQuery(query).get(); + Assert.assertEquals(3, relations.size()); + Assert.assertTrue(relations.contains(relationA)); + Assert.assertTrue(relations.contains(relationB)); + Assert.assertTrue(relations.contains(relationC)); } @Test @@ -253,6 +260,12 @@ public abstract class BaseRelationServiceTest extends AbstractServiceTest { Assert.assertEquals(2, relations.size()); Assert.assertTrue(relations.contains(relationAB)); Assert.assertTrue(relations.contains(relationBC)); + + //Test from cache + relations = relationService.findByQuery(query).get(); + Assert.assertEquals(2, relations.size()); + Assert.assertTrue(relations.contains(relationAB)); + Assert.assertTrue(relations.contains(relationBC)); }