summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Wall <kwall@apache.org>2014-01-17 12:03:57 +0000
committerKeith Wall <kwall@apache.org>2014-01-17 12:03:57 +0000
commit7460aadbf584d6ee135628ac5f28b1b7ee3ca520 (patch)
tree0171cb5c7b5b02aeaec93643085862713504edb2
parent9bafc0cc7f37dfcc43d09bc9e2310c5e1c208cbf (diff)
downloadqpid-python-7460aadbf584d6ee135628ac5f28b1b7ee3ca520.tar.gz
QPID-5409: Make replication node monitor interval/timeout configurable from the vhost level. Eliminate thread pool
per remote replication node. git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/java-broker-bdb-ha@1559084 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/ReplicatedEnvironmentFacade.java84
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/ReplicatedEnvironmentFacadeFactory.java6
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/RemoteReplicationNode.java37
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/RemoteReplicationNodeFactory.java2
-rw-r--r--qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/ReplicatedEnvironmentFacadeTest.java3
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHost.java6
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java16
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/util/DaemonThreadFactory.java40
8 files changed, 147 insertions, 47 deletions
diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/ReplicatedEnvironmentFacade.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/ReplicatedEnvironmentFacade.java
index 379efef613..e017bf13ad 100644
--- a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/ReplicatedEnvironmentFacade.java
+++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/ReplicatedEnvironmentFacade.java
@@ -38,13 +38,16 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.log4j.Logger;
@@ -53,6 +56,7 @@ import org.apache.qpid.server.replication.ReplicationGroupListener;
import org.apache.qpid.server.store.StoreFuture;
import org.apache.qpid.server.store.berkeleydb.replication.RemoteReplicationNode;
import org.apache.qpid.server.store.berkeleydb.replication.RemoteReplicationNodeFactory;
+import org.apache.qpid.server.util.DaemonThreadFactory;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
@@ -80,7 +84,11 @@ import com.sleepycat.je.rep.util.ReplicationGroupAdmin;
public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChangeListener
{
+ public static final String GROUP_CHECK_INTERVAL_PROPERTY_NAME = "qpid.bdb.ha.group_check_interval";
+
private static final Logger LOGGER = Logger.getLogger(ReplicatedEnvironmentFacade.class);
+ private static final long DEFAULT_GROUP_CHECK_INTERVAL = 1000l;
+ private static final long GROUP_CHECK_INTERVAL = Long.getLong(GROUP_CHECK_INTERVAL_PROPERTY_NAME, DEFAULT_GROUP_CHECK_INTERVAL);
@SuppressWarnings("serial")
private static final Map<String, String> REPCONFIG_DEFAULTS = Collections.unmodifiableMap(new HashMap<String, String>()
@@ -136,11 +144,11 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan
private final Map<String, String> _environmentParameters;
private final Map<String, String> _replicationEnvironmentParameters;
private final String _name;
- private final ExecutorService _restartEnvironmentExecutor = Executors.newFixedThreadPool(1);
+ private final ExecutorService _restartEnvironmentExecutor;
private final ScheduledExecutorService _groupChangeExecutor;
private final AtomicReference<State> _state = new AtomicReference<State>(State.INITIAL);
private final ConcurrentMap<String, Database> _databases = new ConcurrentHashMap<String, Database>();
- private final ConcurrentMap<String, org.apache.qpid.server.model.ReplicationNode> _remoteReplicationNodes = new ConcurrentHashMap<String, org.apache.qpid.server.model.ReplicationNode>();
+ private final ConcurrentMap<String, RemoteReplicationNode> _remoteReplicationNodes = new ConcurrentHashMap<String, RemoteReplicationNode>();
private final RemoteReplicationNodeFactory _remoteReplicationNodeFactory;
private volatile CommitThreadWrapper _commitThreadWrapper;
@@ -167,19 +175,13 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan
_environmentParameters = (Map<String, String>)replicationNode.getAttribute(PARAMETERS);
_replicationEnvironmentParameters = (Map<String, String>)replicationNode.getAttribute(REPLICATION_PARAMETERS);
- _groupChangeExecutor = Executors.newScheduledThreadPool(1, new ThreadFactory()
- {
- @Override
- public Thread newThread(Runnable r)
- {
- return new Thread(r, "GroupChangeLearner_" + _groupName);
- }
- });
+ _restartEnvironmentExecutor = Executors.newFixedThreadPool(1, new DaemonThreadFactory("Environment-Restarter:" + _groupName));
+ _groupChangeExecutor = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors() + 1, new DaemonThreadFactory("Group-Change-Learner:" + _groupName));
+
_remoteReplicationNodeFactory = remoteReplicationNodeFactory;
_state.set(State.OPENING);
- //TODO: add ability to alter the execution period
- _groupChangeExecutor.scheduleWithFixedDelay(new GroupChangeLearner(), 1, 1, TimeUnit.SECONDS);
-
+ _groupChangeExecutor.scheduleWithFixedDelay(new GroupChangeLearner(), 0, GROUP_CHECK_INTERVAL, TimeUnit.MILLISECONDS);
+ _groupChangeExecutor.schedule(new RemoteNodeStateLearner(), _remoteReplicationNodeFactory.getRemoteNodeMonitorInterval(), TimeUnit.MILLISECONDS);
_environment = createEnvironment();
populateExistingRemoteReplicationNodes();
_commitThreadWrapper = startCommitThread(_name, _environment);
@@ -809,6 +811,60 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan
}
}
+ //TODO: move the class into external class
+ private class RemoteNodeStateLearner implements Callable<Void>
+ {
+ @Override
+ public Void call()
+ {
+ long remoteNodeMonitorInterval = _remoteReplicationNodeFactory.getRemoteNodeMonitorInterval();
+ try
+ {
+ Set<Future<Void>> futures = new HashSet<Future<Void>>();
+ for (Map.Entry<String, RemoteReplicationNode> entry : _remoteReplicationNodes.entrySet())
+ {
+ final RemoteReplicationNode node = entry.getValue();
+ Future<Void> future = _groupChangeExecutor.submit(new Callable<Void>()
+ {
+ @Override
+ public Void call()
+ {
+ node.updateNodeState();
+ return null;
+ }
+ });
+ futures.add(future);
+ }
+
+ for (Future<Void> future : futures)
+ {
+ try
+ {
+ future.get(remoteNodeMonitorInterval, TimeUnit.MILLISECONDS);
+ }
+ catch (InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ }
+ catch (ExecutionException e)
+ {
+ LOGGER.warn("Cannot update node state for group " + _groupName, e.getCause());
+ }
+ catch (TimeoutException e)
+ {
+ LOGGER.warn("Timeout whilst updating node state for group " + _groupName);
+ future.cancel(true);
+ }
+ }
+ }
+ finally
+ {
+ _groupChangeExecutor.schedule(this, remoteNodeMonitorInterval, TimeUnit.MILLISECONDS);
+ }
+ return null;
+ }
+ }
+
private class LoggingAsyncExceptionListener implements ExceptionListener
{
@Override
diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/ReplicatedEnvironmentFacadeFactory.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/ReplicatedEnvironmentFacadeFactory.java
index 5eeda17373..44f809a70b 100644
--- a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/ReplicatedEnvironmentFacadeFactory.java
+++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/ReplicatedEnvironmentFacadeFactory.java
@@ -83,5 +83,11 @@ public class ReplicatedEnvironmentFacadeFactory implements EnvironmentFacadeFact
attributes.put(ReplicationNode.HOST_PORT, replicationNode.getHostName() + ":" + replicationNode.getPort());
return new RemoteReplicationNode(replicationNode, groupName, _virtualHost, _virtualHost.getTaskExecutor());
}
+
+ @Override
+ public long getRemoteNodeMonitorInterval()
+ {
+ return (Long)_virtualHost.getAttribute(VirtualHost.REMOTE_REPLICATION_NODE_MONITOR_INTERVAL);
+ }
}
}
diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/RemoteReplicationNode.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/RemoteReplicationNode.java
index df2eddad89..bff20fb306 100644
--- a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/RemoteReplicationNode.java
+++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/RemoteReplicationNode.java
@@ -24,10 +24,6 @@ import java.io.IOException;
import java.security.AccessControlException;
import java.util.Collection;
import java.util.Collections;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
import org.apache.qpid.server.configuration.updater.TaskExecutor;
@@ -48,17 +44,12 @@ import com.sleepycat.je.rep.utilint.ServiceDispatcher.ServiceConnectFailedExcept
/**
* Represents a remote replication node in a BDB group.
*/
-public class RemoteReplicationNode extends AbstractAdapter implements ReplicationNode, Runnable
+public class RemoteReplicationNode extends AbstractAdapter implements ReplicationNode
{
private static final Logger LOGGER = Logger.getLogger(RemoteReplicationNode.class);
- //TODO: add attributes for setting the intervals below
- private static final int DEFAULT_SOCKET_TIMEOUT = 10000;
- private static final long DEFAULT_STATE_UPDATE_INTERVAL = 1000; //TODO: set it to bigger value
-
- // TODO: needs to be shared between all remote nodes
- private final ScheduledExecutorService _updateStateExecutor;
private final com.sleepycat.je.rep.ReplicationNode _replicationNode;
+ private final VirtualHost _virtualHost;
private final String _hostPort;
private final String _groupName;
@@ -73,18 +64,7 @@ public class RemoteReplicationNode extends AbstractAdapter implements Replicatio
_groupName = groupName;
_hostPort = replicationNode.getHostName() + ":" + replicationNode.getPort();
_replicationNode = replicationNode;
- _updateStateExecutor = Executors.newScheduledThreadPool(1, new ThreadFactory()
- {
- @Override
- public Thread newThread(Runnable r)
- {
- return new Thread(r, "Remote node state updater " + getName() + "-" + getAttribute(GROUP_NAME));
- }
- });
-
- //TODO: add attribute for update interval
- long stateUpdateInterval = DEFAULT_STATE_UPDATE_INTERVAL;
- _updateStateExecutor.schedule(this, stateUpdateInterval, TimeUnit.MILLISECONDS);
+ _virtualHost = virtualHost;
}
@Override
@@ -166,7 +146,6 @@ public class RemoteReplicationNode extends AbstractAdapter implements Replicatio
{
if (desiredState == State.STOPPED)
{
- _updateStateExecutor.shutdown();
return true;
}
else
@@ -206,9 +185,10 @@ public class RemoteReplicationNode extends AbstractAdapter implements Replicatio
return super.getAttribute(name);
}
- private void updateNodeState()
+ public void updateNodeState()
{
- DbPing ping = new DbPing(_replicationNode, _groupName, DEFAULT_SOCKET_TIMEOUT);
+ Long monitorTimeout = (Long)_virtualHost.getAttribute(VirtualHost.REMOTE_REPLICATION_NODE_MONITOR_TIMEOUT);
+ DbPing ping = new DbPing(_replicationNode, _groupName, monitorTimeout.intValue());
String oldRole = _role;
long oldJoinTime = _joinTime;
long oldTransactionId = _lastTransactionId;
@@ -247,9 +227,4 @@ public class RemoteReplicationNode extends AbstractAdapter implements Replicatio
}
}
- @Override
- public void run()
- {
- updateNodeState();
- }
}
diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/RemoteReplicationNodeFactory.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/RemoteReplicationNodeFactory.java
index 31b55d6574..e02c40009b 100644
--- a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/RemoteReplicationNodeFactory.java
+++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/RemoteReplicationNodeFactory.java
@@ -23,4 +23,6 @@ package org.apache.qpid.server.store.berkeleydb.replication;
public interface RemoteReplicationNodeFactory
{
RemoteReplicationNode create(com.sleepycat.je.rep.ReplicationNode jeNode, String groupName);
+
+ long getRemoteNodeMonitorInterval();
}
diff --git a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/ReplicatedEnvironmentFacadeTest.java b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/ReplicatedEnvironmentFacadeTest.java
index 050d0c7747..ca06db5400 100644
--- a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/ReplicatedEnvironmentFacadeTest.java
+++ b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/ReplicatedEnvironmentFacadeTest.java
@@ -109,6 +109,9 @@ public class ReplicatedEnvironmentFacadeTest extends EnvironmentFacadeTestCase
public void setUp() throws Exception
{
super.setUp();
+
+ when(_virtualHost.getAttribute(VirtualHost.REMOTE_REPLICATION_NODE_MONITOR_INTERVAL)).thenReturn(100L);
+ when(_virtualHost.getAttribute(VirtualHost.REMOTE_REPLICATION_NODE_MONITOR_TIMEOUT)).thenReturn(100L);
}
@Override
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHost.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHost.java
index 48c35797a4..35235daf94 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHost.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHost.java
@@ -91,6 +91,8 @@ public interface VirtualHost extends ConfiguredObject
String CONFIG_PATH = "configPath";
String QUIESCE_ON_MASTER_CHANGE = "quiesceOnMasterChange";
+ String REMOTE_REPLICATION_NODE_MONITOR_INTERVAL = "remoteReplicationNodeMonitorInterval";
+ String REMOTE_REPLICATION_NODE_MONITOR_TIMEOUT = "remoteReplicationNodeMonitorTimeout";
// Attributes
public static final Collection<String> AVAILABLE_ATTRIBUTES =
@@ -126,7 +128,9 @@ public interface VirtualHost extends ConfiguredObject
QUEUE_ALERT_THRESHOLD_QUEUE_DEPTH_BYTES,
QUEUE_ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES,
CONFIG_PATH,
- QUIESCE_ON_MASTER_CHANGE));
+ QUIESCE_ON_MASTER_CHANGE,
+ REMOTE_REPLICATION_NODE_MONITOR_INTERVAL,
+ REMOTE_REPLICATION_NODE_MONITOR_TIMEOUT));
int CURRENT_CONFIG_VERSION = 3;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java
index 57bf80a883..9fd1815b67 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java
@@ -97,8 +97,22 @@ public final class VirtualHostAdapter extends AbstractAdapter implements Virtual
put(STORE_TYPE, String.class);
put(CONFIG_PATH, String.class);
put(STATE, State.class);
+ put(REMOTE_REPLICATION_NODE_MONITOR_INTERVAL, Long.class);
+ put(REMOTE_REPLICATION_NODE_MONITOR_TIMEOUT, Long.class);
+ put(QUIESCE_ON_MASTER_CHANGE, Boolean.class);
}});
+ private static final long DEFAULT_REMOTE_REPLICATION_NODE_MONITOR_INTERVAL = 10000L;
+ private static final long DEFAULT_REMOTE_REPLICATION_NODE_MONITOR_TIMEOUT = 1000L;
+
+ @SuppressWarnings("serial")
+ static final Map<String, Object> DEFAULTS = new HashMap<String, Object>()
+ {{
+ put(REMOTE_REPLICATION_NODE_MONITOR_INTERVAL, DEFAULT_REMOTE_REPLICATION_NODE_MONITOR_INTERVAL);
+ put(REMOTE_REPLICATION_NODE_MONITOR_TIMEOUT, DEFAULT_REMOTE_REPLICATION_NODE_MONITOR_TIMEOUT);
+ put(QUIESCE_ON_MASTER_CHANGE, false);
+ }};
+
private org.apache.qpid.server.virtualhost.VirtualHost _virtualHost;
private final Map<AMQConnectionModel, ConnectionAdapter> _connectionAdapters =
@@ -120,7 +134,7 @@ public final class VirtualHostAdapter extends AbstractAdapter implements Virtual
public VirtualHostAdapter(UUID id, Map<String, Object> attributes, Broker broker, StatisticsGatherer brokerStatisticsGatherer, TaskExecutor taskExecutor)
{
- super(id, null, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES, false), taskExecutor, false);
+ super(id, DEFAULTS, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES, false), taskExecutor, false);
_taskExecutor = taskExecutor;
_broker = broker;
_brokerStatisticsGatherer = brokerStatisticsGatherer;
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/util/DaemonThreadFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/util/DaemonThreadFactory.java
new file mode 100644
index 0000000000..4f1f830fd0
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/util/DaemonThreadFactory.java
@@ -0,0 +1,40 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.util;
+
+import java.util.concurrent.ThreadFactory;
+
+public final class DaemonThreadFactory implements ThreadFactory
+{
+ private String _threadName;
+ public DaemonThreadFactory(String threadName)
+ {
+ _threadName = threadName;
+ }
+
+ @Override
+ public Thread newThread(Runnable r)
+ {
+ Thread thread = new Thread(r, _threadName);
+ thread.setDaemon(true);
+ return thread;
+ }
+} \ No newline at end of file