Skip to content

Commit

Permalink
#43: Lazy datasource creation + aligned open/closed/recreate operatio…
Browse files Browse the repository at this point in the history
…ns to allow multiple gateway open and close
  • Loading branch information
martinbielmannicube committed Sep 6, 2019
1 parent c7d85e1 commit 4c8dac6
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 48 deletions.
Expand Up @@ -123,29 +123,10 @@ public void dropHandlers() throws PersistencyException {

}

private void recreateDS(boolean autoCommit) {
HikariConfig config = new HikariConfig();
JooqHandler.ds.copyStateTo(config);
config.setAutoCommit(autoCommit);
config.addDataSourceProperty("autoCommit", autoCommit);
HikariDataSource newDs = new HikariDataSource(config);
JooqHandler.ds = newDs;
}

@Override
public void close() throws PersistencyException {
Logger.msg(1, "JooqClusterStorage.close()");
try {
HikariPoolMXBean poolBean = JooqHandler.ds.getHikariPoolMXBean();
while (poolBean.getActiveConnections() > 0) {
poolBean.softEvictConnections();
}
JooqHandler.ds.close();
}
catch (Exception e) {
Logger.error(e);
throw new PersistencyException(e.getMessage());
}
JooqHandler.closeDataSource();
}

@Override
Expand All @@ -156,9 +137,8 @@ public void postBoostrap() throws PersistencyException {

// after the the bootstrap the DataSOurce needs to be reset to its original config
if (!JooqHandler.autoCommit) {
//Close current DS and create a new one
close();
recreateDS(JooqHandler.autoCommit);
//Create a new data source with original autocommit setting
JooqHandler.recreateDataSource(JooqHandler.autoCommit);
}
}

Expand All @@ -173,9 +153,8 @@ public void postStartServer() throws PersistencyException {
public void postConnect() throws PersistencyException {
// the DataSource need to be set to autocommit for the the bootstrap to work
if (!JooqHandler.autoCommit) {
//Close current DS and create a new one
close();
recreateDS(true);
//recreate a new DS with auto-commit forced to true
JooqHandler.recreateDataSource(true);
}

JooqHandler.connect().transaction(nested -> {
Expand All @@ -186,7 +165,7 @@ public void postConnect() throws PersistencyException {

@Override
public void begin(Object locker) throws PersistencyException {
if (!JooqHandler.ds.isAutoCommit() && locker == null) {
if (!JooqHandler.getDataSource().isAutoCommit() && locker == null) {
throw new PersistencyException("locker cannot be null when autoCommit is false");
}
Connection conn = JooqHandler.connect().configuration().connectionProvider().acquire();
Expand All @@ -195,13 +174,13 @@ public void begin(Object locker) throws PersistencyException {
}

private DSLContext retrieveContext(Object locker) throws PersistencyException {
if (JooqHandler.ds.isAutoCommit()) return JooqHandler.connect();
else return JooqHandler.connect(connectionMap.get(locker));
if (JooqHandler.getDataSource().isAutoCommit()) return JooqHandler.connect();
else return JooqHandler.connect(connectionMap.get(locker));
}

@Override
public void commit(Object locker) throws PersistencyException {
if (!JooqHandler.ds.isAutoCommit() && locker == null) {
if (!JooqHandler.getDataSource().isAutoCommit() && locker == null) {
throw new PersistencyException("locker cannot be null when autoCommit is false");
}

Expand All @@ -218,7 +197,7 @@ public void commit(Object locker) throws PersistencyException {

try {
Connection conn = connectionMap.remove(locker);
if (!JooqHandler.ds.isAutoCommit()) {
if (!JooqHandler.getDataSource().isAutoCommit()) {
conn.commit();
}
conn.close();
Expand All @@ -231,7 +210,7 @@ public void commit(Object locker) throws PersistencyException {

@Override
public void abort(Object locker) throws PersistencyException {
if (!JooqHandler.ds.isAutoCommit() && locker == null) {
if (!JooqHandler.getDataSource().isAutoCommit() && locker == null) {
throw new PersistencyException("locker cannot be null when autoCommit is false");
}

Expand All @@ -247,7 +226,7 @@ public void abort(Object locker) throws PersistencyException {
Logger.msg(1, "JooqClusterStorage.abort()");
try {
Connection conn = connectionMap.remove(locker);
if (!JooqHandler.ds.isAutoCommit()) {
if (!JooqHandler.getDataSource().isAutoCommit()) {
conn.rollback();
}
conn.close();
Expand Down Expand Up @@ -362,7 +341,7 @@ public void put(ItemPath itemPath, C2KLocalObject obj) throws PersistencyExcepti

@Override
public void put(ItemPath itemPath, C2KLocalObject obj, Object locker) throws PersistencyException {
if (!JooqHandler.ds.isAutoCommit() && locker == null) {
if (!JooqHandler.getDataSource().isAutoCommit() && locker == null) {
throw new PersistencyException("locker cannot be null when autoCommit is false");
}

Expand Down Expand Up @@ -394,7 +373,7 @@ public void delete(ItemPath itemPath, String path) throws PersistencyException {

@Override
public void delete(ItemPath itemPath, String path, Object locker) throws PersistencyException {
if (!JooqHandler.ds.isAutoCommit() && locker == null) {
if (!JooqHandler.getDataSource().isAutoCommit() && locker == null) {
throw new PersistencyException("locker cannot be null when autoCommit is false");
}

Expand Down
58 changes: 46 additions & 12 deletions jooqdb/src/main/java/org/cristalise/storage/jooqdb/JooqHandler.java
Expand Up @@ -25,6 +25,7 @@
import static org.jooq.impl.DSL.select;
import static org.jooq.impl.DSL.using;

import com.zaxxer.hikari.HikariPoolMXBean;
import java.sql.Connection;
import java.sql.Timestamp;
import java.util.Arrays;
Expand Down Expand Up @@ -165,18 +166,15 @@ public abstract class JooqHandler {
public static final Boolean autoCommit = Gateway.getProperties().getBoolean(JooqHandler.JOOQ_AUTOCOMMIT, false);
public static final SQLDialect dialect = SQLDialect.valueOf(Gateway.getProperties().getString(JooqHandler.JOOQ_DIALECT, "POSTGRES"));

public static HikariDataSource ds;

static {
if (StringUtils.isAnyBlank(uri, user, pwd)) {
throw new IllegalArgumentException("JOOQ (uri, user, password) config values must not be blank");
}

HikariConfig config = new HikariConfig();
private static HikariDataSource ds = null;
private static HikariConfig config;

public static synchronized HikariDataSource getDataSource(){
if (StringUtils.isAnyBlank(uri, user, pwd))
throw new IllegalArgumentException("JOOQ (uri, user, password) config values must not be blank");
config = new HikariConfig();
config.setPoolName("CRISTAL-iSE-HikariCP");
config.setRegisterMbeans(true);

config.setJdbcUrl(uri);
config.setUsername(user);
config.setPassword(pwd);
Expand All @@ -191,14 +189,50 @@ public abstract class JooqHandler {
config.addDataSourceProperty( "prepStmtCacheSqlLimit", "2048");
config.addDataSourceProperty( "autoCommit", autoCommit);

ds = new HikariDataSource(config);

Logger.msg(8, "JooqHandler.static() - uri:'"+uri+"' user:'"+user+"' dialect:'"+dialect+"'");

if (ds == null){
config.setAutoCommit(autoCommit);
ds = new HikariDataSource(config);
Logger.msg(3, "JooqHandler.getDataSource() create datasource %s", ds);
}
return ds;
}

public static synchronized void recreateDataSource(boolean forcedAutoCommit) throws PersistencyException {
if (ds == null)
throw new PersistencyException("Cannot recreate a null data source");
Logger.msg(3, "JooqHandler.recreateDataSource() autocomit=%b", forcedAutoCommit);
HikariConfig config = new HikariConfig();
ds.copyStateTo(config);
config.setAutoCommit(forcedAutoCommit);
config.addDataSourceProperty("autoCommit", forcedAutoCommit);
closeDataSource();
HikariDataSource newDs = new HikariDataSource(config);
ds = newDs;
}

public static synchronized void closeDataSource() throws PersistencyException {
try {
if (ds != null){
HikariPoolMXBean poolBean = ds.getHikariPoolMXBean();
Logger.msg(3, "JooqHandler.closeDataSource() active connections=%d", poolBean.getActiveConnections());
while (poolBean.getActiveConnections() > 0) {
poolBean.softEvictConnections();
}
ds.close();
ds = null;
}
}
catch (Exception e) {
Logger.error(e);
throw new PersistencyException(e.getMessage());
}
}

public static DSLContext connect() throws PersistencyException {
try {
return using(ds, dialect);
return using(getDataSource(), dialect);
}
catch (Exception ex) {
Logger.error("JooqHandler could not connect to URI '"+uri+"' with user '"+user+"'");
Expand Down
Expand Up @@ -124,7 +124,7 @@ public void initializeDirectory() throws ObjectNotFoundException {
@Override
public void close() {
try {
JooqHandler.connect().close();
JooqHandler.closeDataSource();
}
catch (DataAccessException | PersistencyException e) {
Logger.error(e);
Expand Down

0 comments on commit 4c8dac6

Please sign in to comment.