package org.distributeme.core.concurrencycontrol;
import net.anotheria.util.StringUtils;
import org.configureme.ConfigurationManager;
import org.distributeme.core.ClientSideCallContext;
import org.distributeme.core.ServerSideCallContext;
import java.util.concurrent.atomic.AtomicLong;
/**
* This implementation of a concurrencycontrolstrategy is based on constants which are annotated to the target interface.
*
* @author lrosenberg
* @version $Id: $Id
*/
public class ConfigurationBasedConcurrencyControlStrategy implements ConcurrencyControlStrategy{
/**
* Configuration instance.
*/
private ConcurrencyControlStrategyConfiguration configuration = new ConcurrencyControlStrategyConfiguration();
/**
* Currently active client side requests.
*/
private AtomicLong clientSideRequestCount = new AtomicLong(0);
/**
* Currently active server side requests.
*/
private AtomicLong serverSideRequestCount = new AtomicLong(0);
/** {@inheritDoc} */
@Override
public void customize(String parameter) {
//if configuration parameter contains a comma its old style configuration parameter.
if (parameter.indexOf(',')!=-1)
customizeFromAnnotationParameter(parameter);
else
customizeFromConfigurationName(parameter);
}
private void customizeFromConfigurationName(String parameter){
try{
ConfigurationManager.INSTANCE.configureAs(configuration, parameter);
}catch(IllegalArgumentException e){
throw new IllegalArgumentException("Can't find configuration "+parameter+" for concurrency config");
}
}
private void customizeFromAnnotationParameter(String parameter){
if (parameter==null || parameter.length()==0)
throw new IllegalArgumentException("Empty or null parameter, expected clientlimit,serverlimit");
String limits[] = StringUtils.tokenize(parameter, ',');
int aClientSideLimit = Integer.parseInt(limits[0]);
if (aClientSideLimit>0)
configuration.setClientSideLimit(aClientSideLimit);
int aServerSideLimit = 0;
if (limits.length>1)
aServerSideLimit = Integer.parseInt(limits[1]);
if (aServerSideLimit>0)
configuration.setServerSideLimit(aServerSideLimit);
}
/** {@inheritDoc} */
@Override
public void notifyClientSideCallStarted(ClientSideCallContext context) {
if (clientSideRequestCount.incrementAndGet()>configuration.getClientSideLimit()){
clientSideRequestCount.decrementAndGet();
throw new OutgoingRequestRefusedException();
}
}
/** {@inheritDoc} */
@Override
public void notifyClientSideCallFinished(ClientSideCallContext context) {
clientSideRequestCount.decrementAndGet();
}
/** {@inheritDoc} */
@Override
public void notifyServerSideCallStarted(ServerSideCallContext context) {
if (serverSideRequestCount.incrementAndGet()>configuration.getServerSideLimit()){
serverSideRequestCount.decrementAndGet();
throw new ServerRefusedRequestException();
}
}
/** {@inheritDoc} */
@Override
public void notifyServerSideCallFinished(ServerSideCallContext context) {
serverSideRequestCount.decrementAndGet();
}
/** {@inheritDoc} */
@Override public String toString(){
return getClass().getSimpleName()+" with limits configuration: "+configuration;
}
}