use of org.scale7.cassandra.pelops.Cluster in project scale7-pelops by s7.
the class CommonsBackedPool method getConnectionExcept.
@Override
public IPooledConnection getConnectionExcept(Set<String> avoidNodes) throws NoConnectionsAvailableException {
PooledNode node = null;
IPooledConnection connection = null;
long timeout = -1;
while (connection == null) {
if (timeout == -1) {
// first run through calc the timeout for the next loop
// (this makes debugging easier)
int maxWait = getPolicy().getMaxWaitForConnection();
timeout = maxWait > 0 ? System.currentTimeMillis() + maxWait : Long.MAX_VALUE;
} else if (timeout < System.currentTimeMillis()) {
logger.debug("Max wait time for connection exceeded");
break;
}
node = nodeSelectionStrategy.select(this, nodes.keySet(), avoidNodes);
// if the strategy was unable to choose a node (all suspended?) then sleep for a bit and loop
if (node == null) {
logger.debug("The node selection strategy was unable to choose a node, sleeping before trying again...");
try {
Thread.sleep(DEFAULT_WAIT_PERIOD);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
continue;
}
try {
logger.debug("Attempting to borrow free connection for node '{}'", node.getAddress());
// note that if no connections are currently available for this node then the pool will sleep for
// DEFAULT_WAIT_PERIOD milliseconds
connection = pool.borrowObject(node.getAddress());
} catch (IllegalStateException e) {
throw new PelopsException("The pool has been shutdown", e);
} catch (Exception e) {
if (e instanceof NoSuchElementException) {
logger.debug("No free connections available for node '{}'. Trying another node...", node.getAddress());
} else if (e instanceof TTransportException) {
logger.warn(String.format("A TTransportException was thrown while attempting to create a connection to '%s'. " + "This node will be suspended for %sms. Trying another node...", node.getAddress(), this.policy.getNodeDownSuspensionMillis()));
node.suspendForMillis(this.policy.getNodeDownSuspensionMillis());
} else
logger.warn(String.format("An exception was thrown while attempting to create a connection to '%s'. " + "Trying another node...", node.getAddress()), e);
// try and avoid this node on the next trip through the loop
if (avoidNodes == null)
avoidNodes = new HashSet<String>(10);
avoidNodes.add(node.getAddress());
}
}
if (node == null) {
logger.error("Failed to get a connection within the configured wait time because there are no available nodes. " + "This possibly indicates that either the suspension strategy is too aggressive or that your " + "cluster is in a bad way.");
throw new NoConnectionsAvailableException("Failed to get a connection within the configured max wait time.");
}
if (connection == null) {
logger.error("Failed to get a connection within the maximum allowed wait time. " + "Try increasing the either the number of allowed connections or the max wait time.");
throw new NoConnectionsAvailableException("Failed to get a connection within the configured max wait time.");
}
logger.debug("Borrowing connection '{}'", connection);
statistics.connectionsActive.incrementAndGet();
reportConnectionBorrowed(connection.getNode().getAddress());
return connection;
}
use of org.scale7.cassandra.pelops.Cluster in project scale7-pelops by s7.
the class CommonsBackedPoolIntegrationTest method testInitWithDownedNode.
/**
* Test initialization with static node list that contains an offline node.
* https://github.com/s7/scale7-pelops/issues#issue/24
*/
@Test
public void testInitWithDownedNode() throws Exception {
final int timeout = 2000;
// allowed timeout deviation in percentage
final int allowedDeviation = 10;
Cluster cluster = new Cluster(new String[] { RPC_LISTEN_ADDRESS, "192.0.2.0" }, new IConnection.Config(RPC_PORT, true, timeout), false);
CommonsBackedPool.Policy config = new CommonsBackedPool.Policy();
// disable the background thread
config.setTimeBetweenScheduledMaintenanceTaskRunsMillis(-1);
config.setMaxActivePerNode(1);
long startMillis = System.currentTimeMillis();
CommonsBackedPool pool = new CommonsBackedPool(cluster, AbstractIntegrationTest.KEYSPACE, config, new OperandPolicy(), new LeastLoadedNodeSelectionStrategy(), new NoOpNodeSuspensionStrategy(), new DescribeVersionConnectionValidator());
double totalMillis = System.currentTimeMillis() - startMillis;
String reason = String.format("actual timeout should be within %d%% of the configured", allowedDeviation);
assertThat(reason, totalMillis, closeTo(timeout, (allowedDeviation / 100.0) * timeout));
try {
pool.createSelector();
} finally {
pool.shutdown();
}
}
use of org.scale7.cassandra.pelops.Cluster in project scale7-pelops by s7.
the class CommonsBackedPoolFactoryBeanIntegrationTest method testAfterProperties.
/**
* Tests the factory bean works as expected when operand or pool policy instances are provided.
* @throws Exception if an error occurs
*/
@Test
public void testAfterProperties() throws Exception {
OperandPolicy operandPolicy = new OperandPolicy();
CommonsBackedPool.Policy policy = new CommonsBackedPool.Policy();
LeastLoadedNodeSelectionStrategy nodeSelectionStrategy = new LeastLoadedNodeSelectionStrategy();
NoOpNodeSuspensionStrategy nodeSuspensionStrategy = new NoOpNodeSuspensionStrategy();
NoOpConnectionValidator connectionValidator = new NoOpConnectionValidator();
CommonsBackedPoolFactoryBean factoryBean = new CommonsBackedPoolFactoryBean();
factoryBean.setCluster(AbstractIntegrationTest.cluster);
factoryBean.setKeyspace(AbstractIntegrationTest.KEYSPACE);
factoryBean.setPolicy(policy);
factoryBean.setOperandPolicy(operandPolicy);
factoryBean.setNodeSelectionStrategy(nodeSelectionStrategy);
factoryBean.setNodeSuspensionStrategy(nodeSuspensionStrategy);
factoryBean.setConnectionValidator(connectionValidator);
assertNull("The factory should not have created the pool at this point", factoryBean.getObject());
try {
factoryBean.afterPropertiesSet();
CommonsBackedPool pool = (CommonsBackedPool) factoryBean.getObject();
assertNotNull("The factory didn't initialize the pool", pool);
assertTrue("The factory didn't use the provided operand policy instance", operandPolicy == pool.getOperandPolicy());
assertTrue("The factory didn't use the provided config instance", policy == pool.getPolicy());
assertTrue("The factory didn't use the provided config instance", cluster == pool.getCluster());
assertTrue("The factory didn't use the provided node selection instance", nodeSelectionStrategy == pool.getNodeSelectionStrategy());
assertTrue("The factory didn't use the provided node suspension instance", nodeSuspensionStrategy == pool.getNodeSuspensionStrategy());
assertTrue("The factory didn't use the provided connection validator instance", connectionValidator == pool.getConnectionValidator());
} finally {
factoryBean.destroy();
}
}
use of org.scale7.cassandra.pelops.Cluster in project scale7-pelops by s7.
the class AbstractIntegrationTest method setup.
/**
* Starts embedded cassandra server.
*
* @throws Exception
* if an error occurs
*/
public static void setup(List<CfDef> columnDefinitions) throws Exception {
if (cassandraServer == null) {
cassandraServer = new EmbeddedCassandraServer();
cassandraServer.start();
// wait until cassandra server starts up. could wait less time, but
// 2 seconds to be sure.
Thread.sleep(2000);
}
colFamilyDefs = columnDefinitions;
keyspaceManager = new KeyspaceManager(cluster);
columnFamilyManager = new ColumnFamilyManager(cluster, KEYSPACE);
List<KsDef> keyspaces = keyspaceManager.getKeyspaceNames();
for (KsDef ksDef : keyspaces) if (ksDef.name.equals(KEYSPACE)) {
keyspaceManager.dropKeyspace(KEYSPACE);
}
KsDef keyspaceDefinition = new KsDef(KEYSPACE, KeyspaceManager.KSDEF_STRATEGY_SIMPLE, new ArrayList<CfDef>());
Map<String, String> strategyOptions = new HashMap<String, String>();
strategyOptions.put("replication_factor", "1");
keyspaceDefinition.setStrategy_options(strategyOptions);
for (CfDef colFamilyDef : colFamilyDefs) {
keyspaceDefinition.addToCf_defs(colFamilyDef);
}
keyspaceManager.addKeyspace(keyspaceDefinition);
}
use of org.scale7.cassandra.pelops.Cluster in project scale7-pelops by s7.
the class Pelops method addPool.
/**
* Add a new Thrift connection pool for a specific cluster and keyspace. The name given to the pool is later used
* when creating operands such as <code>Mutator</code> and <code>Selector</code>.
* @param poolName A name used to reference the pool e.g. "MainDatabase" or "LucandraIndexes"
* @param cluster The Cassandra cluster that network connections will be made to
* @param keyspace The keyspace in the Cassandra cluster against which pool operations will apply
*/
public static void addPool(String poolName, Cluster cluster, String keyspace) {
IThriftPool pool = new CommonsBackedPool(cluster, keyspace);
addPool(poolName, pool);
}
Aggregations