Repository: activemq-artemis
Updated Branches:
  refs/heads/1.x e3f426b4e -> 3388f68fe


ARTEMIS-1788 JDBC HA should use JDBC Network Timeout

(cherry picked from commit 1a3c1feb0a6a352a2ca4088b19f3d3b9b46a4833)


Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/3388f68f
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/3388f68f
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/3388f68f

Branch: refs/heads/1.x
Commit: 3388f68feadcb344942b784488bc118f86f0cad5
Parents: e3f426b
Author: Francesco Nigro <[email protected]>
Authored: Mon Apr 9 16:26:37 2018 +0200
Committer: Francesco Nigro <[email protected]>
Committed: Wed Apr 18 17:06:21 2018 +0200

----------------------------------------------------------------------
 .../jdbc/store/drivers/AbstractJDBCDriver.java  |  3 +
 .../core/server/impl/jdbc/JdbcNodeManager.java  | 86 ++++++++++++++------
 .../impl/jdbc/JdbcSharedStateManager.java       | 23 ++++++
 docs/user-manual/en/persistence.md              |  1 +
 4 files changed, 90 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3388f68f/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/AbstractJDBCDriver.java
----------------------------------------------------------------------
diff --git 
a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/AbstractJDBCDriver.java
 
b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/AbstractJDBCDriver.java
index c7a944e..e421a3b 100644
--- 
a/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/AbstractJDBCDriver.java
+++ 
b/artemis-jdbc-store/src/main/java/org/apache/activemq/artemis/jdbc/store/drivers/AbstractJDBCDriver.java
@@ -141,6 +141,9 @@ public abstract class AbstractJDBCDriver {
                throw e;
             }
          }
+         if (this.networkTimeoutMillis >= 0 && this.networkTimeoutExecutor == 
null) {
+            logger.warn("Unable to set a network timeout on the JDBC 
connection: networkTimeoutExecutor is null");
+         }
          if (this.networkTimeoutMillis >= 0 && this.networkTimeoutExecutor != 
null) {
             try {
                connection.setNetworkTimeout(this.networkTimeoutExecutor, 
this.networkTimeoutMillis);

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3388f68f/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcNodeManager.java
----------------------------------------------------------------------
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcNodeManager.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcNodeManager.java
index 36cc6e8..465680f 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcNodeManager.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcNodeManager.java
@@ -60,6 +60,7 @@ public final class JdbcNodeManager extends NodeManager {
                                       ScheduledExecutorService 
scheduledExecutorService,
                                       ExecutorFactory executorFactory,
                                       IOCriticalErrorListener 
ioCriticalErrorListener) {
+      validateTimeoutConfiguration(configuration);
       if (configuration.getDataSource() != null) {
          final SQLProvider.Factory sqlProviderFactory;
          if (configuration.getSqlProviderFactory() != null) {
@@ -69,6 +70,7 @@ public final class JdbcNodeManager extends NodeManager {
          }
          final String brokerId = java.util.UUID.randomUUID().toString();
          return usingDataSource(brokerId,
+                                configuration.getJdbcNetworkTimeout(),
                                 configuration.getJdbcLockExpirationMillis(),
                                 configuration.getJdbcLockRenewPeriodMillis(),
                                 
configuration.getJdbcLockAcquisitionTimeoutMillis(),
@@ -82,6 +84,7 @@ public final class JdbcNodeManager extends NodeManager {
          final SQLProvider sqlProvider = 
JDBCUtils.getSQLProvider(configuration.getJdbcDriverClassName(), 
configuration.getNodeManagerStoreTableName(), 
SQLProvider.DatabaseStoreType.NODE_MANAGER);
          final String brokerId = java.util.UUID.randomUUID().toString();
          return usingConnectionUrl(brokerId,
+                                   configuration.getJdbcNetworkTimeout(),
                                    configuration.getJdbcLockExpirationMillis(),
                                    
configuration.getJdbcLockRenewPeriodMillis(),
                                    
configuration.getJdbcLockAcquisitionTimeoutMillis(),
@@ -95,18 +98,25 @@ public final class JdbcNodeManager extends NodeManager {
       }
    }
 
-   static JdbcNodeManager usingDataSource(String brokerId,
-                                          long lockExpirationMillis,
-                                          long lockRenewPeriodMillis,
-                                          long lockAcquisitionTimeoutMillis,
-                                          long maxAllowedMillisFromDbTime,
-                                          DataSource dataSource,
-                                          SQLProvider provider,
-                                          ScheduledExecutorService 
scheduledExecutorService,
-                                          ExecutorFactory executorFactory,
-                                          IOCriticalErrorListener 
ioCriticalErrorListener) {
+   private static JdbcNodeManager usingDataSource(String brokerId,
+                                                  int networkTimeoutMillis,
+                                                  long lockExpirationMillis,
+                                                  long lockRenewPeriodMillis,
+                                                  long 
lockAcquisitionTimeoutMillis,
+                                                  long 
maxAllowedMillisFromDbTime,
+                                                  DataSource dataSource,
+                                                  SQLProvider provider,
+                                                  ScheduledExecutorService 
scheduledExecutorService,
+                                                  ExecutorFactory 
executorFactory,
+                                                  IOCriticalErrorListener 
ioCriticalErrorListener) {
       return new JdbcNodeManager(
-         () -> JdbcSharedStateManager.usingDataSource(brokerId, 
lockExpirationMillis, maxAllowedMillisFromDbTime, dataSource, provider),
+         () -> JdbcSharedStateManager.usingDataSource(brokerId,
+                                                      networkTimeoutMillis,
+                                                      executorFactory == null 
? null : executorFactory.getExecutor(),
+                                                      lockExpirationMillis,
+                                                      
maxAllowedMillisFromDbTime,
+                                                      dataSource,
+                                                      provider),
          false,
          lockRenewPeriodMillis,
          lockAcquisitionTimeoutMillis,
@@ -115,19 +125,27 @@ public final class JdbcNodeManager extends NodeManager {
          ioCriticalErrorListener);
    }
 
-   public static JdbcNodeManager usingConnectionUrl(String brokerId,
-                                                    long lockExpirationMillis,
-                                                    long lockRenewPeriodMillis,
-                                                    long 
lockAcquisitionTimeoutMillis,
-                                                    long 
maxAllowedMillisFromDbTime,
-                                                    String jdbcUrl,
-                                                    String driverClass,
-                                                    SQLProvider provider,
-                                                    ScheduledExecutorService 
scheduledExecutorService,
-                                                    ExecutorFactory 
executorFactory,
-                                                    IOCriticalErrorListener 
ioCriticalErrorListener) {
+   private static JdbcNodeManager usingConnectionUrl(String brokerId,
+                                                     int networkTimeoutMillis,
+                                                     long lockExpirationMillis,
+                                                     long 
lockRenewPeriodMillis,
+                                                     long 
lockAcquisitionTimeoutMillis,
+                                                     long 
maxAllowedMillisFromDbTime,
+                                                     String jdbcUrl,
+                                                     String driverClass,
+                                                     SQLProvider provider,
+                                                     ScheduledExecutorService 
scheduledExecutorService,
+                                                     ExecutorFactory 
executorFactory,
+                                                     IOCriticalErrorListener 
ioCriticalErrorListener) {
       return new JdbcNodeManager(
-         () -> JdbcSharedStateManager.usingConnectionUrl(brokerId, 
lockExpirationMillis, maxAllowedMillisFromDbTime, jdbcUrl, driverClass, 
provider),
+         () -> JdbcSharedStateManager.usingConnectionUrl(brokerId,
+                                                         networkTimeoutMillis,
+                                                         executorFactory == 
null ? null : executorFactory.getExecutor(),
+                                                         lockExpirationMillis,
+                                                         
maxAllowedMillisFromDbTime,
+                                                         jdbcUrl,
+                                                         driverClass,
+                                                         provider),
          false,
          lockRenewPeriodMillis,
          lockAcquisitionTimeoutMillis,
@@ -136,6 +154,28 @@ public final class JdbcNodeManager extends NodeManager {
          ioCriticalErrorListener);
    }
 
+   private static void 
validateTimeoutConfiguration(DatabaseStorageConfiguration configuration) {
+      final long lockExpiration = configuration.getJdbcLockExpirationMillis();
+      if (lockExpiration <= 0) {
+         throw new IllegalArgumentException("jdbc-lock-expiration should be 
positive");
+      }
+      final long lockRenewPeriod = 
configuration.getJdbcLockRenewPeriodMillis();
+      if (lockRenewPeriod <= 0) {
+         throw new IllegalArgumentException("jdbc-lock-renew-period should be 
positive");
+      }
+      if (lockRenewPeriod >= lockExpiration) {
+         throw new IllegalArgumentException("jdbc-lock-renew-period should be 
< jdbc-lock-expiration");
+      }
+      final int networkTimeout = configuration.getJdbcNetworkTimeout();
+      if (networkTimeout >= 0) {
+         if (networkTimeout > lockExpiration) {
+            logger.warn("jdbc-network-timeout isn't properly configured: the 
recommended value is <= jdbc-lock-expiration");
+         }
+      } else {
+         logger.warn("jdbc-network-timeout isn't properly configured: the 
recommended value is <= jdbc-lock-expiration");
+      }
+   }
+
    private JdbcNodeManager(Supplier<? extends SharedStateManager> 
sharedStateManagerFactory,
                            boolean replicatedBackup,
                            long lockRenewPeriodMillis,

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3388f68f/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcSharedStateManager.java
----------------------------------------------------------------------
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcSharedStateManager.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcSharedStateManager.java
index d14de7a..a8b07e9 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcSharedStateManager.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/jdbc/JdbcSharedStateManager.java
@@ -24,6 +24,7 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.sql.Timestamp;
+import java.util.concurrent.Executor;
 import java.util.function.Supplier;
 
 import org.apache.activemq.artemis.jdbc.store.drivers.AbstractJDBCDriver;
@@ -52,11 +53,14 @@ final class JdbcSharedStateManager extends 
AbstractJDBCDriver implements SharedS
    private long timeDifferenceMillisFromDb = 0;
 
    public static JdbcSharedStateManager usingDataSource(String holderId,
+                                                        int networkTimeout,
+                                                        Executor 
networkTimeoutExecutor,
                                                         long 
locksExpirationMillis,
                                                         long 
maxAllowedMillisFromDbTime,
                                                         DataSource dataSource,
                                                         SQLProvider provider) {
       final JdbcSharedStateManager sharedStateManager = new 
JdbcSharedStateManager(holderId, locksExpirationMillis, 
maxAllowedMillisFromDbTime);
+      sharedStateManager.setNetworkTimeout(networkTimeoutExecutor, 
networkTimeout);
       sharedStateManager.setDataSource(dataSource);
       sharedStateManager.setSqlProvider(provider);
       try {
@@ -73,7 +77,26 @@ final class JdbcSharedStateManager extends 
AbstractJDBCDriver implements SharedS
                                                            String 
jdbcConnectionUrl,
                                                            String 
jdbcDriverClass,
                                                            SQLProvider 
provider) {
+      return JdbcSharedStateManager.usingConnectionUrl(holderId,
+                                                       -1,
+                                                       null,
+                                                       locksExpirationMillis,
+                                                       
maxAllowedMillisFromDbTime,
+                                                       jdbcConnectionUrl,
+                                                       jdbcDriverClass,
+                                                       provider);
+   }
+
+   public static JdbcSharedStateManager usingConnectionUrl(String holderId,
+                                                           int networkTimeout,
+                                                           Executor 
networkTimeoutExecutor,
+                                                           long 
locksExpirationMillis,
+                                                           long 
maxAllowedMillisFromDbTime,
+                                                           String 
jdbcConnectionUrl,
+                                                           String 
jdbcDriverClass,
+                                                           SQLProvider 
provider) {
       final JdbcSharedStateManager sharedStateManager = new 
JdbcSharedStateManager(holderId, locksExpirationMillis, 
maxAllowedMillisFromDbTime);
+      sharedStateManager.setNetworkTimeout(networkTimeoutExecutor, 
networkTimeout);
       sharedStateManager.setJdbcConnectionUrl(jdbcConnectionUrl);
       sharedStateManager.setJdbcDriverClass(jdbcDriverClass);
       sharedStateManager.setSqlProvider(provider);

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3388f68f/docs/user-manual/en/persistence.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/persistence.md 
b/docs/user-manual/en/persistence.md
index b6f0b8b..d5635be 100644
--- a/docs/user-manual/en/persistence.md
+++ b/docs/user-manual/en/persistence.md
@@ -442,6 +442,7 @@ To configure Apache ActiveMQ Artemis to use a database for 
persisting messages a
 
     The JDBC network connection timeout in milliseconds. The default value
     is 20000 milliseconds (ie 20 seconds).
+    When using a shared store it is recommended to set it less then or equal 
to `jdbc-lock-expiration`.
     
 -   `jdbc-lock-renew-period`
 

Reply via email to