use of org.scale7.cassandra.pelops.exceptions.NoConnectionsAvailableException 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.exceptions.NoConnectionsAvailableException in project scale7-pelops by s7.
the class CommonsBackedPoolIntegrationTest method testsScheduledTaskNodeSuspension.
/**
* Test that when a node is suspended all it's connections are terminated and that when it comes good it starts
* returning connections again.
*/
@Test
public void testsScheduledTaskNodeSuspension() throws Exception {
CommonsBackedPool.Policy config = new CommonsBackedPool.Policy();
// disable the background thread
config.setTimeBetweenScheduledMaintenanceTaskRunsMillis(-1);
config.setMaxActivePerNode(1);
final AtomicBoolean suspended = new AtomicBoolean(true);
CommonsBackedPool pool = new CommonsBackedPool(AbstractIntegrationTest.cluster, AbstractIntegrationTest.KEYSPACE, config, new OperandPolicy(), new LeastLoadedNodeSelectionStrategy(), new CommonsBackedPool.INodeSuspensionStrategy() {
@Override
public boolean evaluate(CommonsBackedPool pool, PooledNode node) {
if (suspended.get()) {
// first run through we want to suspend the node
suspended.set(false);
node.setSuspensionState(new CommonsBackedPool.INodeSuspensionState() {
@Override
public boolean isSuspended() {
return true;
}
});
return true;
} else {
// second run through we want the node active
node.setSuspensionState(new CommonsBackedPool.INodeSuspensionState() {
@Override
public boolean isSuspended() {
return false;
}
});
return false;
}
}
}, new NoOpConnectionValidator());
try {
// node not yet suspended
IThriftPool.IPooledConnection connection = pool.getConnection();
connection.release();
// suspend the node
pool.runMaintenanceTasks();
try {
pool.getConnection();
fail("No nodes should be available");
} catch (NoConnectionsAvailableException e) {
// expected
}
// activate the node
pool.runMaintenanceTasks();
// node is now active
connection = pool.getConnection();
connection.release();
} finally {
pool.shutdown();
}
}
use of org.scale7.cassandra.pelops.exceptions.NoConnectionsAvailableException in project scale7-pelops by s7.
the class DebuggingPool method getConnection.
@Override
public IPooledConnection getConnection() throws NoConnectionsAvailableException {
Cluster.Node[] nodes = cluster.getNodes();
int index = nodes.length == 1 ? 0 : random.nextInt(nodes.length);
logger.debug("Using node '{}'", nodes[index]);
if (connection != null && connection.isOpen())
return connection;
try {
connection = new PooledConnection(nodes[index], keyspace);
connection.open();
} catch (Exception e) {
throw new NoConnectionsAvailableException();
}
return connection;
}
Aggregations