From e0d6615c4bac948cb503ccd41cae35b0c0ad9976 Mon Sep 17 00:00:00 2001 From: Kang Dooho Date: Fri, 29 Nov 2024 15:35:51 +0900 Subject: [PATCH 1/4] [APIS-1005] Extends the loadBalance Property of JDBC. --- src/jdbc/cubrid/jdbc/driver/CUBRIDDriver.java | 48 +++++++++++++++---- .../jdbc/driver/ConnectionProperties.java | 39 +++++++++++++-- 2 files changed, 73 insertions(+), 14 deletions(-) diff --git a/src/jdbc/cubrid/jdbc/driver/CUBRIDDriver.java b/src/jdbc/cubrid/jdbc/driver/CUBRIDDriver.java index e27b355..3b6c2dc 100644 --- a/src/jdbc/cubrid/jdbc/driver/CUBRIDDriver.java +++ b/src/jdbc/cubrid/jdbc/driver/CUBRIDDriver.java @@ -87,6 +87,7 @@ public class CUBRIDDriver implements Driver { "jdbc:cubrid(-oracle|-mysql)?:([a-zA-Z_0-9\\.-]*):([0-9]*):([^:]+):([^:]*):([^:]*):(\\?[a-zA-Z_0-9]+=[^&=?]+(&[a-zA-Z_0-9]+=[^&=?]+)*)?"; private static final String CUBRID_JDBC_URL_HEADER = "jdbc:cubrid"; private static final String ENV_JDBC_PROP_NAME = "CUBRID_JDBC_PROP"; + private int conn_count = 0; static { try { @@ -265,15 +266,17 @@ public Connection connect(String url, Properties info) throws SQLException { altHostList.add(st.nextToken()); } - if (connProperties.getConnLoadBal()) { - Collections.shuffle(altHostList); - } - try { - u_con = - (UClientSideConnection) - UJCIManager.connect(altHostList, db, user, pass, resolvedUrl); - } catch (CUBRIDException e) { - throw e; + String loadBalValue = connProperties.getConnLoadBal(); + + synchronized (this) { + adjustHostList(loadBalValue, altHostList); + try { + u_con = + (UClientSideConnection) + UJCIManager.connect(altHostList, db, user, pass, resolvedUrl); + } catch (CUBRIDException e) { + throw e; + } } } else { try { @@ -346,4 +349,31 @@ private boolean existPropertiesFile(String filePath) { File file = new File(filePath); return file.exists(); } + + private void adjustHostList(String loadBalValue, ArrayList altHostList) { + switch (loadBalValue) { + case ConnectionProperties.LB_VAL_TRUE: + Collections.shuffle(altHostList); + break; + case ConnectionProperties.LB_VAL_FALSE: + break; + case ConnectionProperties.LB_VAL_ROUND_ROBIN: + conn_count++; + int index = + (conn_count > altHostList.size()) + ? (conn_count - 1) % altHostList.size() + : conn_count - 1; + Collections.rotate(altHostList, -index); + + if (conn_count >= Integer.MAX_VALUE) { + conn_count = 0; + } + break; + case ConnectionProperties.LB_VAL_SHUFFLE: + Collections.shuffle(altHostList); + break; + default: + throw new IllegalArgumentException("Invalid loadBalValue: " + loadBalValue); + } + } } diff --git a/src/jdbc/cubrid/jdbc/driver/ConnectionProperties.java b/src/jdbc/cubrid/jdbc/driver/ConnectionProperties.java index 33eed86..4a692b0 100644 --- a/src/jdbc/cubrid/jdbc/driver/ConnectionProperties.java +++ b/src/jdbc/cubrid/jdbc/driver/ConnectionProperties.java @@ -43,6 +43,10 @@ public class ConnectionProperties { static ArrayList PROPERTY_LIST = new ArrayList(); + public static final String LB_VAL_TRUE = "true"; + public static final String LB_VAL_FALSE = "false"; + public static final String LB_VAL_SHUFFLE = "sh"; + public static final String LB_VAL_ROUND_ROBIN = "rr"; static { try { @@ -108,8 +112,8 @@ public void setProperties(Properties info) throws SQLException { CUBRIDJDBCErrorCode.invalid_url, " illegal access properties", null); } } - if (this.getConnLoadBal() && this.getAltHosts() == null) { - this.connLoadBal.setValue("false"); + if (!this.getConnLoadBal().equals(LB_VAL_FALSE) && this.getAltHosts() == null) { + this.connLoadBal.setValue(LB_VAL_FALSE); } if (this.getReconnectTime() < (BrokerHealthCheck.MONITORING_INTERVAL / 1000)) { this.rcTime.setValue((Integer) (BrokerHealthCheck.MONITORING_INTERVAL / 1000)); @@ -335,6 +339,30 @@ boolean validateValue(Object o) { } } + class StringLoadBalanceProperty extends ConnectionProperty { + String[] allowableValues = {LB_VAL_TRUE, LB_VAL_FALSE, LB_VAL_SHUFFLE, LB_VAL_ROUND_ROBIN}; + + StringLoadBalanceProperty(String propertyName, Object defaultValue) { + super(propertyName, defaultValue, 0, 0); + } + + String getValueAsString() { + return (String) valueAsObject; + } + + @Override + boolean validateValue(Object o) { + if (o instanceof String) { + for (int i = 0; i < allowableValues.length; i++) { + if (allowableValues[i].equalsIgnoreCase((String) o)) { + return true; + } + } + } + return false; + } + } + BooleanConnectionProperty logOnException = new BooleanConnectionProperty("logOnException", false); @@ -369,7 +397,8 @@ private int getDefaultConnectTimeout() { StringConnectionProperty altHosts = new StringConnectionProperty("altHosts", null); - BooleanConnectionProperty connLoadBal = new BooleanConnectionProperty("loadBalance", false); + StringLoadBalanceProperty connLoadBal = + new StringLoadBalanceProperty("loadBalance", LB_VAL_FALSE); ZeroDateTimeBehaviorConnectionProperty zeroDateTimeBehavior = new ZeroDateTimeBehaviorConnectionProperty( @@ -440,8 +469,8 @@ public String getAltHosts() { return altHosts.getValueAsString(); } - public boolean getConnLoadBal() { - return connLoadBal.getValueAsBoolean(); + public String getConnLoadBal() { + return connLoadBal.getValueAsString(); } public String getZeroDateTimeBehavior() { From e669563b8e244eed8961cb36869f2590c0d45934 Mon Sep 17 00:00:00 2001 From: Kang Dooho Date: Fri, 29 Nov 2024 18:22:49 +0900 Subject: [PATCH 2/4] Changing the scope of a synchronized block --- src/jdbc/cubrid/jdbc/driver/CUBRIDDriver.java | 52 ++++++++----------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/src/jdbc/cubrid/jdbc/driver/CUBRIDDriver.java b/src/jdbc/cubrid/jdbc/driver/CUBRIDDriver.java index 3b6c2dc..3464e88 100644 --- a/src/jdbc/cubrid/jdbc/driver/CUBRIDDriver.java +++ b/src/jdbc/cubrid/jdbc/driver/CUBRIDDriver.java @@ -87,7 +87,7 @@ public class CUBRIDDriver implements Driver { "jdbc:cubrid(-oracle|-mysql)?:([a-zA-Z_0-9\\.-]*):([0-9]*):([^:]+):([^:]*):([^:]*):(\\?[a-zA-Z_0-9]+=[^&=?]+(&[a-zA-Z_0-9]+=[^&=?]+)*)?"; private static final String CUBRID_JDBC_URL_HEADER = "jdbc:cubrid"; private static final String ENV_JDBC_PROP_NAME = "CUBRID_JDBC_PROP"; - private int conn_count = 0; + private int conn_count = 0; static { try { @@ -265,19 +265,17 @@ public Connection connect(String url, Properties info) throws SQLException { while (st.hasMoreTokens()) { altHostList.add(st.nextToken()); } - + String loadBalValue = connProperties.getConnLoadBal(); - - synchronized (this) { + adjustHostList(loadBalValue, altHostList); try { u_con = (UClientSideConnection) - UJCIManager.connect(altHostList, db, user, pass, resolvedUrl); + UJCIManager.connect(altHostList, db, user, pass, resolvedUrl); } catch (CUBRIDException e) { throw e; } - } } else { try { u_con = @@ -349,31 +347,25 @@ private boolean existPropertiesFile(String filePath) { File file = new File(filePath); return file.exists(); } - + private void adjustHostList(String loadBalValue, ArrayList altHostList) { - switch (loadBalValue) { - case ConnectionProperties.LB_VAL_TRUE: - Collections.shuffle(altHostList); - break; - case ConnectionProperties.LB_VAL_FALSE: - break; - case ConnectionProperties.LB_VAL_ROUND_ROBIN: - conn_count++; - int index = - (conn_count > altHostList.size()) - ? (conn_count - 1) % altHostList.size() - : conn_count - 1; - Collections.rotate(altHostList, -index); - - if (conn_count >= Integer.MAX_VALUE) { - conn_count = 0; - } - break; - case ConnectionProperties.LB_VAL_SHUFFLE: - Collections.shuffle(altHostList); - break; - default: - throw new IllegalArgumentException("Invalid loadBalValue: " + loadBalValue); + if ( ConnectionProperties.LB_VAL_TRUE.equals(loadBalValue)) { + Collections.shuffle(altHostList); + } else if (ConnectionProperties.LB_VAL_ROUND_ROBIN.equals(loadBalValue)) { + int count = increment_conn_count(); + int dist = (count > altHostList.size()) ? (count - 1) % altHostList.size() : count - 1; + Collections.rotate(altHostList, -dist); + } else if (ConnectionProperties.LB_VAL_SHUFFLE.equals(loadBalValue)) { + Collections.shuffle(altHostList); + } else if (ConnectionProperties.LB_VAL_FALSE.equals(loadBalValue)) { + // do nothing + } else { + throw new IllegalArgumentException("Invalid loadBalValue: " + loadBalValue); } } + + private synchronized int increment_conn_count() { + conn_count = conn_count + 1; + return conn_count; + } } From 99977019f80f0c0b912afaab35f14f5073e406a2 Mon Sep 17 00:00:00 2001 From: Kang Dooho Date: Mon, 2 Dec 2024 15:35:17 +0900 Subject: [PATCH 3/4] Change the default value of loadBalance to Round-Robin --- src/jdbc/cubrid/jdbc/driver/CUBRIDDriver.java | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/jdbc/cubrid/jdbc/driver/CUBRIDDriver.java b/src/jdbc/cubrid/jdbc/driver/CUBRIDDriver.java index 3464e88..266281b 100644 --- a/src/jdbc/cubrid/jdbc/driver/CUBRIDDriver.java +++ b/src/jdbc/cubrid/jdbc/driver/CUBRIDDriver.java @@ -87,7 +87,7 @@ public class CUBRIDDriver implements Driver { "jdbc:cubrid(-oracle|-mysql)?:([a-zA-Z_0-9\\.-]*):([0-9]*):([^:]+):([^:]*):([^:]*):(\\?[a-zA-Z_0-9]+=[^&=?]+(&[a-zA-Z_0-9]+=[^&=?]+)*)?"; private static final String CUBRID_JDBC_URL_HEADER = "jdbc:cubrid"; private static final String ENV_JDBC_PROP_NAME = "CUBRID_JDBC_PROP"; - private int conn_count = 0; + private int conn_count = 0; static { try { @@ -265,17 +265,17 @@ public Connection connect(String url, Properties info) throws SQLException { while (st.hasMoreTokens()) { altHostList.add(st.nextToken()); } - + String loadBalValue = connProperties.getConnLoadBal(); - - adjustHostList(loadBalValue, altHostList); - try { - u_con = - (UClientSideConnection) - UJCIManager.connect(altHostList, db, user, pass, resolvedUrl); - } catch (CUBRIDException e) { - throw e; - } + + adjustHostList(loadBalValue, altHostList); + try { + u_con = + (UClientSideConnection) + UJCIManager.connect(altHostList, db, user, pass, resolvedUrl); + } catch (CUBRIDException e) { + throw e; + } } else { try { u_con = @@ -347,23 +347,22 @@ private boolean existPropertiesFile(String filePath) { File file = new File(filePath); return file.exists(); } - + private void adjustHostList(String loadBalValue, ArrayList altHostList) { - if ( ConnectionProperties.LB_VAL_TRUE.equals(loadBalValue)) { - Collections.shuffle(altHostList); - } else if (ConnectionProperties.LB_VAL_ROUND_ROBIN.equals(loadBalValue)) { + if (ConnectionProperties.LB_VAL_TRUE.equals(loadBalValue) + || ConnectionProperties.LB_VAL_ROUND_ROBIN.equals(loadBalValue)) { int count = increment_conn_count(); int dist = (count > altHostList.size()) ? (count - 1) % altHostList.size() : count - 1; Collections.rotate(altHostList, -dist); } else if (ConnectionProperties.LB_VAL_SHUFFLE.equals(loadBalValue)) { Collections.shuffle(altHostList); - } else if (ConnectionProperties.LB_VAL_FALSE.equals(loadBalValue)) { - // do nothing + } else if (ConnectionProperties.LB_VAL_FALSE.equals(loadBalValue)) { + // do nothing } else { throw new IllegalArgumentException("Invalid loadBalValue: " + loadBalValue); } } - + private synchronized int increment_conn_count() { conn_count = conn_count + 1; return conn_count; From 469c042eec240aa2978c162b083b1e8028fd684f Mon Sep 17 00:00:00 2001 From: Kang Dooho Date: Mon, 2 Dec 2024 16:34:36 +0900 Subject: [PATCH 4/4] Prevent conn_count value overflow --- src/jdbc/cubrid/jdbc/driver/CUBRIDDriver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jdbc/cubrid/jdbc/driver/CUBRIDDriver.java b/src/jdbc/cubrid/jdbc/driver/CUBRIDDriver.java index 266281b..90263a4 100644 --- a/src/jdbc/cubrid/jdbc/driver/CUBRIDDriver.java +++ b/src/jdbc/cubrid/jdbc/driver/CUBRIDDriver.java @@ -364,7 +364,7 @@ private void adjustHostList(String loadBalValue, ArrayList altHostList) } private synchronized int increment_conn_count() { - conn_count = conn_count + 1; + conn_count = (conn_count >= Integer.MAX_VALUE) ? 1 : conn_count + 1; return conn_count; } }