Skip to content

Commit

Permalink
feat(engine): provide SPI for custom deployment cache implementation
Browse files Browse the repository at this point in the history
* sets maximum cache capacity as well

related to #CAM-6397,#CAM-6393
  • Loading branch information
Johannes Heinemann committed Sep 26, 2016
1 parent 847cbaa commit 61c0bdd
Show file tree
Hide file tree
Showing 15 changed files with 556 additions and 396 deletions.
2 changes: 1 addition & 1 deletion bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
<version.mybatis>3.2.8</version.mybatis>
<version.joda-time>2.1</version.joda-time>
<version.uuid-generator>3.1.2</version.uuid-generator>
<version.camunda.commons>1.4.0-alpha2</version.camunda.commons>
<version.camunda.commons>1.4.0-alpha3</version.camunda.commons>
<version.camunda.connect>1.0.3</version.camunda.connect>
<version.camunda.spin>1.3.0</version.camunda.spin>
<version.camunda.template-engines>1.0.1</version.camunda.template-engines>
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.camunda.bpm.engine.impl.persistence.deploy;

import org.camunda.commons.utils.cache.Cache;

/**
* <p>Builds the caches for the {@link DeploymentCache}.</p>
*/
public interface CacheFactory {

/**
* Creates a cache that does not exceed a specified number of elements.
*
* @param maxNumberOfElementsInCache
* The maximum number of elements that is allowed within the cache at the same time.
* @return
* The cache to be created.
*/
public Cache createCache(int maxNumberOfElementsInCache);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.camunda.bpm.engine.impl.persistence.deploy;


import org.camunda.bpm.engine.impl.db.DbEntity;
import org.camunda.commons.utils.cache.Cache;
import org.camunda.commons.utils.cache.ConcurrentLruCache;

/**
* <p>Provides the default cache implementation for the deployment caches see {@link DeploymentCache}.</p>
*
* @author Johannes Heinemann
*/
public class DefaultCacheFactory implements CacheFactory{

@Override
public Cache createCache(int maxNumberOfElementsInCache) {
return new ConcurrentLruCache<String, DbEntity>(maxNumberOfElementsInCache);
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,6 @@

package org.camunda.bpm.engine.impl.test;

import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import org.camunda.bpm.engine.HistoryService;
import org.camunda.bpm.engine.ProcessEngine;
import org.camunda.bpm.engine.ProcessEngineConfiguration;
Expand Down Expand Up @@ -56,10 +45,17 @@
import org.camunda.bpm.engine.test.RequiredHistoryLevel;
import org.camunda.bpm.model.bpmn.BpmnModelInstance;
import org.camunda.bpm.model.cmmn.CmmnModelInstance;
import org.camunda.commons.utils.cache.Cache;
import org.camunda.commons.utils.cache.ConcurrentLruCache;
import org.junit.Assert;
import org.junit.runner.Description;
import org.slf4j.Logger;

import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;


/**
* @author Tom Baeyens
Expand Down Expand Up @@ -320,27 +316,35 @@ public static String assertAndEnsureCleanDeploymentCache(ProcessEngine processEn
ProcessEngineConfigurationImpl processEngineConfiguration = ((ProcessEngineImpl) processEngine).getProcessEngineConfiguration();
DeploymentCache deploymentCache = processEngineConfiguration.getDeploymentCache();

Map<String, ProcessDefinitionEntity> processDefinitionCache = deploymentCache.getProcessDefinitionCache();
if (!processDefinitionCache.isEmpty()) {
outputMessage.append("\tProcess Definition Cache: ").append(processDefinitionCache.keySet()).append("\n");
Cache<String, ProcessDefinitionEntity> processDefinitionCache = deploymentCache.getProcessDefinitionCache();
ConcurrentLruCache<String, ProcessDefinitionEntity> defaultProcessDefinitionCache =
(ConcurrentLruCache) processDefinitionCache;
if (!defaultProcessDefinitionCache.isEmpty()) {
outputMessage.append("\tProcess Definition Cache: ").append(defaultProcessDefinitionCache.keySet()).append("\n");
processDefinitionCache.clear();
}

Map<String, BpmnModelInstance> bpmnModelInstanceCache = deploymentCache.getBpmnModelInstanceCache();
if (!bpmnModelInstanceCache.isEmpty()) {
outputMessage.append("\tBPMN Model Instance Cache: ").append(bpmnModelInstanceCache.keySet()).append("\n");
Cache<String, BpmnModelInstance> bpmnModelInstanceCache = deploymentCache.getBpmnModelInstanceCache();
ConcurrentLruCache<String, BpmnModelInstance> defaultBpmnModelInstanceCache =
(ConcurrentLruCache) bpmnModelInstanceCache;
if (!defaultBpmnModelInstanceCache.isEmpty()) {
outputMessage.append("\tBPMN Model Instance Cache: ").append(defaultBpmnModelInstanceCache.keySet()).append("\n");
bpmnModelInstanceCache.clear();
}

Map<String, CaseDefinitionEntity> caseDefinitionCache = deploymentCache.getCaseDefinitionCache();
if (!caseDefinitionCache.isEmpty()) {
outputMessage.append("\tCase Definition Cache: ").append(caseDefinitionCache.keySet()).append("\n");
Cache<String, CaseDefinitionEntity> caseDefinitionCache = deploymentCache.getCaseDefinitionCache();
ConcurrentLruCache<String, CaseDefinitionEntity> defaultCaseDefinitionCache =
(ConcurrentLruCache) caseDefinitionCache;
if (!defaultCaseDefinitionCache.isEmpty()) {
outputMessage.append("\tCase Definition Cache: ").append(defaultCaseDefinitionCache.keySet()).append("\n");
caseDefinitionCache.clear();
}

Map<String, CmmnModelInstance> cmmnModelInstanceCache = deploymentCache.getCmmnModelInstanceCache();
if (!cmmnModelInstanceCache.isEmpty()) {
outputMessage.append("\tCMMN Model Instance Cache: ").append(cmmnModelInstanceCache.keySet()).append("\n");
Cache<String, CmmnModelInstance> cmmnModelInstanceCache = deploymentCache.getCmmnModelInstanceCache();
ConcurrentLruCache<String, CmmnModelInstance> defaultCmmnModelInstanceCache =
(ConcurrentLruCache) cmmnModelInstanceCache;
if (!defaultCmmnModelInstanceCache.isEmpty()) {
outputMessage.append("\tCMMN Model Instance Cache: ").append(defaultCmmnModelInstanceCache.keySet()).append("\n");
cmmnModelInstanceCache.clear();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@

import org.camunda.bpm.engine.impl.test.PluggableProcessEngineTestCase;
import org.camunda.bpm.engine.repository.Deployment;
import org.camunda.bpm.engine.repository.ProcessDefinition;
import org.camunda.bpm.model.bpmn.Bpmn;
import org.camunda.bpm.model.bpmn.BpmnModelInstance;
import org.camunda.commons.utils.cache.Cache;

/**
* @author Roman Smirnov
Expand Down Expand Up @@ -57,8 +59,13 @@ public void testNoRegistrationCheckIfNoProcessApplicationIsDeployed() {
// this logic should not be executed.
runtimeService.startProcessInstanceByKey(PROCESS_KEY);

ProcessDefinition version1 = repositoryService.createProcessDefinitionQuery().deploymentId(deployment1.getId()).singleResult();
ProcessDefinition version2 = repositoryService.createProcessDefinitionQuery().deploymentId(deployment2.getId()).singleResult();

// accordingly the process definition cache should only contain the latest version now
assertEquals(1, processEngineConfiguration.getDeploymentCache().getProcessDefinitionCache().size());
Cache cache = processEngineConfiguration.getDeploymentCache().getProcessDefinitionCache();
assertNotNull(cache.get(version2.getId()));
assertNull(cache.get(version1.getId()));

deleteDeployments(deployment1, deployment2);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package org.camunda.bpm.engine.test.api.cfg;

import org.camunda.bpm.engine.impl.persistence.deploy.DeploymentCache;
import org.camunda.bpm.engine.impl.test.ResourceProcessEngineTestCase;
import org.camunda.bpm.engine.test.Deployment;
import org.junit.Test;

/**
* @author Johannes Heinemann
*/
public class DeploymentCacheCfgTest extends ResourceProcessEngineTestCase {


public DeploymentCacheCfgTest() {
super("org/camunda/bpm/engine/test/api/cfg/customized.cacheFactory.camunda.cfg.xml");
}

@Test
@Deployment(resources =
{"org/camunda/bpm/engine/test/api/cfg/MaxCacheSizeCfgTest.testDefaultCacheRemovesLRUElementWhenMaxSizeIsExceeded.bpmn20.xml"})
public void testPlugInOwnCacheImplementation() {
// The 'customized.cacheFactory.camunda.cfg.xml' sets a customized cache factory that uses the
// default cache implementation, but limits the maximum number of elements within the cache to 2.
// According to the least recently used principle of the default implementation should the first
// process not be contained in the cache anymore.

// given
String processDefinitionIdOne = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("one")
.singleResult()
.getId();
String processDefinitionIdTwo = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("two")
.singleResult()
.getId();
String processDefinitionIdThree = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("three")
.singleResult()
.getId();


// when
DeploymentCache deploymentCache = processEngineConfiguration.getDeploymentCache();

// then
assertNotNull(deploymentCache.getProcessDefinitionCache().get(processDefinitionIdTwo));
assertNotNull(deploymentCache.getProcessDefinitionCache().get(processDefinitionIdThree));

assertNull(deploymentCache.getProcessDefinitionCache().get(processDefinitionIdOne));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.camunda.bpm.engine.test.api.cfg;

import org.camunda.bpm.engine.impl.persistence.deploy.DeploymentCache;
import org.camunda.bpm.engine.impl.test.ResourceProcessEngineTestCase;
import org.camunda.bpm.engine.test.Deployment;
import org.junit.Test;

/**
* @author Johannes Heinemann
*/
public class MaxCacheSizeCfgTest extends ResourceProcessEngineTestCase {

public MaxCacheSizeCfgTest() {
super("org/camunda/bpm/engine/test/api/cfg/cacheSize.reduced.camunda.cfg.xml");
}

@Test
@Deployment
public void testDefaultCacheRemovesLRUElementWhenMaxSizeIsExceeded() {
// The 'cacheSize.reduced.camunda.cfg.xml' sets the maximum number of elements of the
// to 2. Accordingly, one process should not be contained in the cache anymore.

// given
String processDefinitionIdOne = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("one")
.singleResult()
.getId();
String processDefinitionIdTwo = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("two")
.singleResult()
.getId();
String processDefinitionIdThree = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("three")
.singleResult()
.getId();

// when
DeploymentCache deploymentCache = processEngineConfiguration.getDeploymentCache();

// then
int numberOfProcessesInCache = 0;
numberOfProcessesInCache +=
deploymentCache.getProcessDefinitionCache().get(processDefinitionIdOne) == null ? 0 : 1;
numberOfProcessesInCache +=
deploymentCache.getProcessDefinitionCache().get(processDefinitionIdTwo) == null ? 0 : 1;
numberOfProcessesInCache +=
deploymentCache.getProcessDefinitionCache().get(processDefinitionIdThree) == null ? 0 : 1;

assertTrue(numberOfProcessesInCache == 2);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.camunda.bpm.engine.test.api.cfg;

import org.camunda.bpm.engine.impl.db.DbEntity;
import org.camunda.bpm.engine.impl.persistence.deploy.DefaultCacheFactory;
import org.camunda.commons.utils.cache.Cache;
import org.camunda.commons.utils.cache.ConcurrentLruCache;

/**
* Cache that has a maximum capacity two elements.
*
* @author Johannes Heinemann
*/
public class MyCacheFactory extends DefaultCacheFactory {

@Override
public Cache createCache(int maxNumberOfElementsInCache) {
return new MyMostRecentlyUsedCache<String, DbEntity>(maxNumberOfElementsInCache);
}

private class MyMostRecentlyUsedCache<K, V> extends ConcurrentLruCache<K, V> {

public MyMostRecentlyUsedCache(int capacity) {
super(2);
}

}
}
Loading

0 comments on commit 61c0bdd

Please sign in to comment.