@Test public void testFramedTransport() throws HectorException { CassandraHost cassandraHost = new CassandraHost("localhost", 9170); cassandraHost.setUseThriftFramedTransport(true); client = new CassandraClientFactory(pools, cassandraHost, monitor).create(); assertTrue(client.getCassandra().getInputProtocol().getTransport() instanceof TFramedTransport); }
public ConcurrentHClientPool(CassandraHost host) throws SQLException { this.cassandraHost = host; ds = new CassandraDataSource( cassandraHost.getHost(), cassandraHost.getPort(), cassandraHost.getKeyspaceName(), cassandraHost.getUser(), cassandraHost.getPassword()); availableConnectionQueue = new ArrayBlockingQueue<CassandraConnectionHandle>(cassandraHost.getMaxActive(), true); // This counter can be offset by as much as the number of threads. activeConnectionCount = new AtomicInteger(0); realActiveConnectionCount = new AtomicInteger(0); numBlocked = new AtomicInteger(); active = new AtomicBoolean(true); maxWaitTimeWhenExhausted = cassandraHost.getMaxWaitTimeWhenExhausted() < 0 ? 0 : cassandraHost.getMaxWaitTimeWhenExhausted(); for (int i = 0; i < cassandraHost.getMaxActive() / 3; i++) { availableConnectionQueue.add(createConnection()); } if (log.isDebugEnabled()) { log.debug( "Concurrent Host pool started with {} active clients; max: {} exhausted wait: {}", new Object[] {getNumIdle(), cassandraHost.getMaxActive(), maxWaitTimeWhenExhausted}); } }
@Override public Set<String> getExhaustedPoolNames() { Set<String> ret = new HashSet<String>(); for (CassandraHost host : connectionManager.getDownedHosts()) { ret.add(host.toString()); } return ret; }
@Override public List<String> getKnownHosts() { List<String> hosts = new ArrayList<String>(); for (CassandraHost cassandraHost : connectionManager.getHosts()) { hosts.add(cassandraHost.toString()); } return hosts; }
@Override public Set<String> getSuspendedCassandraHosts() { Set<CassandraHost> hosts = connectionManager.getSuspendedCassandraHosts(); Set<String> hostsStr = new HashSet<String>(); for (CassandraHost host : hosts) { hostsStr.add(host.getName()); } return hostsStr; }
/** * Used when we still have room to grow. Return an Connection without having to wait on polling * logic. (But still increment all the counters) * * @return * @throws SQLException */ private CassandraConnectionHandle createConnection() throws SQLException { if (log.isDebugEnabled()) { log.debug("Creation of new connection"); } try { return new CassandraConnectionHandle( ds.getConnection(cassandraHost.getUser(), cassandraHost.getPassword()), cassandraHost); } catch (SQLException e) { log.debug("Unable to open transport to " + cassandraHost.getName()); throw e; } }
@Override public void releaseClient(CassandraConnectionHandle conn) throws SQLException { boolean open; try { open = !conn.isClosed(); } catch (SQLException e) { // Tight to Cassandra Driver implementation. It should not happen. open = false; } if (open) { if (active.get()) { addClientToPoolGently(conn); } else { log.info("Open client released to in-active pool for host {}. Closing.", cassandraHost); closeConnection(conn); } } else { try { addClientToPoolGently(createConnection()); } catch (SQLException e) { log.info("Unable to reopen a connection. Bad server. Message: " + e.getMessage()); } } realActiveConnectionCount.decrementAndGet(); activeConnectionCount.decrementAndGet(); if (log.isDebugEnabled()) { log.debug("Status of releaseClient {} to queue: {}", cassandraHost.getHost(), open); } }
private void closeConnection(CassandraConnectionHandle conn) { try { conn.getInternalConnection().close(); } catch (SQLException e) { log.error("Error closgin connection for: " + cassandraHost.getHost()); } }
private CassandraConnectionHandle waitForConnection() { CassandraConnectionHandle conn = null; numBlocked.incrementAndGet(); // blocked take on the queue if we are configured to wait forever if (log.isDebugEnabled()) { log.debug("blocking on queue - current block count {}", numBlocked.get()); } try { // wait and catch, creating a new one if the counts have changed. Infinite wait should just // recurse. if (maxWaitTimeWhenExhausted == 0) { while (conn == null && active.get()) { try { conn = availableConnectionQueue.poll(100, TimeUnit.MILLISECONDS); } catch (InterruptedException ie) { log.error("InterruptedException poll operation on retry forever", ie); break; } } } else { try { conn = availableConnectionQueue.poll(maxWaitTimeWhenExhausted, TimeUnit.MILLISECONDS); if (conn == null) { throw new HPoolExhaustedException( String.format( "maxWaitTimeWhenExhausted exceeded for thread %s on host %s", new Object[] {Thread.currentThread().getName(), cassandraHost.getName()})); } } catch (InterruptedException ie) { // monitor.incCounter(Counter.POOL_EXHAUSTED); log.error("Cassandra client acquisition interrupted", ie); } } } finally { numBlocked.decrementAndGet(); } return conn; }
@Override public CassandraConnectionHandle borrowClient() throws SQLException { if (!active.get()) { throw new HPoolInnactiveException("Attempt to borrow on in-active pool: " + getName()); } CassandraConnectionHandle conn = availableConnectionQueue.poll(); int currentActiveClients = activeConnectionCount.incrementAndGet(); try { if (conn == null) { if (currentActiveClients <= cassandraHost.getMaxActive()) { conn = createConnection(); } else { // We can't grow so let's wait for a connection to become available. conn = waitForConnection(); } } if (conn == null) { // Abnormal situation. throw new HectorException( "HConnectionManager returned a null client after aquisition - are we shutting down?"); } } catch (RuntimeException e) { activeConnectionCount.decrementAndGet(); throw e; } catch (SQLException e) { activeConnectionCount.decrementAndGet(); throw e; } realActiveConnectionCount.incrementAndGet(); return conn; }
@Override public int getMaxActive() { return cassandraHost.getMaxActive(); }
@Override public int getNumBeforeExhausted() { return cassandraHost.getMaxActive() - realActiveConnectionCount.get(); }
@Override public String getName() { return String.format("<ConcurrentCassandraClientPoolByHost>:{%s}", cassandraHost.getName()); }