Page MenuHomec4science

MySQLConnectionPool.java
No OneTemporary

File Metadata

Created
Sun, Apr 28, 14:44

MySQLConnectionPool.java

package com.yahoo.ycsb.db;
import com.github.jasync.sql.db.Configuration;
import com.github.jasync.sql.db.mysql.MySQLConnection;
import com.github.jasync.sql.db.mysql.pool.MySQLConnectionFactory;
import com.github.jasync.sql.db.pool.PoolAlreadyTerminatedException;
import com.github.jasync.sql.db.pool.PoolExhaustedException;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;
/**
*
*/
public class MySQLConnectionPool {
private final MySQLConnectionFactory connectionFactory;
private ConcurrentLinkedQueue<MySQLConnection> available = new ConcurrentLinkedQueue<>();
private ConcurrentHashMap<MySQLConnection, MySQLConnection> checkedOut = new ConcurrentHashMap<>();
private AtomicLong connectionCount = new AtomicLong(0);
private boolean closed = false;
private ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
private final long maxConnections;
public MySQLConnectionPool(Configuration config, long maxConnections) {
this.connectionFactory = new MySQLConnectionFactory(config);
this.maxConnections = maxConnections;
if (maxConnections <= 0) {
throw new IllegalArgumentException("maxConnections cannot be less than or equal to 0.");
}
}
public MySQLConnection take() {
if (closed) {
throw new PoolAlreadyTerminatedException();
}
MySQLConnection connection = available.poll();
if (null == connection) {
long connIdx = connectionCount.getAndUpdate(count -> count == maxConnections ? count : count + 1);
if (connIdx == maxConnections) {
throw new PoolExhaustedException("No connections are available.");
}
connection = connectionFactory.create();
}
checkedOut.put(connection, connection);
return connection;
}
public void giveBack(MySQLConnection connection) {
if (!checkedOut.containsKey(connection)) {
throw new IllegalArgumentException("This connection is not part of the pool or was already returned.");
}
if (connectionFactory.validate(connection).isSuccess()) {
checkedOut.remove(connection);
available.offer(connection);
}
}
public long getTotalConnections() {
return connectionCount.get();
}
public int getNumTakenConnections() {
return checkedOut.size();
}
public int getNumAvailableConnections() {
return available.size();
}
private void closeAllConnections() {
available.forEach((MySQLConnection::disconnect));
}
public void close() {
closed = true;
closeAllConnections();
if (!checkedOut.isEmpty()) {
ses.scheduleAtFixedRate(() -> {
if (checkedOut.isEmpty()) {
closeAllConnections();
ses.shutdown();
} else {
System.out.println("Waiting 100ms for all connections to be released.");
}
}, 0, 100, TimeUnit.MILLISECONDS);
}
}
}

Event Timeline