You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rl...@apache.org on 2017/07/10 20:58:54 UTC
[14/18] ambari git commit: AMBARI-21427. Assigning hosts concurrently
to same config group may fail with
'org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException:
Config group already exist'. (stoader)
AMBARI-21427. Assigning hosts concurrently to same config group may fail with 'org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException: Config group already exist'. (stoader)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/3c9f125c
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/3c9f125c
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/3c9f125c
Branch: refs/heads/branch-feature-AMBARI-20859
Commit: 3c9f125cc08269558f35a971c321777d331de1ca
Parents: 7f3d3b2
Author: Toader, Sebastian <st...@hortonworks.com>
Authored: Mon Jul 10 13:02:20 2017 +0200
Committer: Toader, Sebastian <st...@hortonworks.com>
Committed: Mon Jul 10 13:02:45 2017 +0200
----------------------------------------------------------------------
.../ambari/server/topology/AmbariContext.java | 28 +++++++++++++++++---
1 file changed, 24 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/3c9f125c/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
index 9b64edc..dee0e6c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
@@ -30,6 +30,7 @@ import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.Lock;
import javax.annotation.Nullable;
import javax.inject.Inject;
@@ -81,6 +82,7 @@ import org.slf4j.LoggerFactory;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.Striped;
import com.google.inject.Provider;
@@ -121,6 +123,16 @@ public class AmbariContext {
private final static Logger LOG = LoggerFactory.getLogger(AmbariContext.class);
+
+ /**
+ * When config groups are created using Blueprints these are created when
+ * hosts join a hostgroup and are added to the corresponding config group.
+ * Since hosts join in parallel there might be a race condition in creating
+ * the config group a host is to be added to. Thus we need to synchronize
+ * the creation of config groups with the same name.
+ */
+ private Striped<Lock> configGroupCreateLock = Striped.lazyWeakLock(1);
+
public boolean isClusterKerberosEnabled(long clusterId) {
Cluster cluster;
try {
@@ -341,11 +353,17 @@ public class AmbariContext {
}
public void registerHostWithConfigGroup(final String hostName, final ClusterTopology topology, final String groupName) {
+ String qualifiedGroupName = getConfigurationGroupName(topology.getBlueprint().getName(), groupName);
+
+ Lock configGroupLock = configGroupCreateLock.get(qualifiedGroupName);
+
try {
+ configGroupLock.lock();
+
boolean hostAdded = RetryHelper.executeWithRetry(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
- return addHostToExistingConfigGroups(hostName, topology, groupName);
+ return addHostToExistingConfigGroups(hostName, topology, qualifiedGroupName);
}
});
if (!hostAdded) {
@@ -355,6 +373,9 @@ public class AmbariContext {
LOG.error("Unable to register config group for host: ", e);
throw new RuntimeException("Unable to register config group for host: " + hostName);
}
+ finally {
+ configGroupLock.unlock();
+ }
}
public RequestStatusResponse installHost(String hostName, String clusterName, Collection<String> skipInstallForComponents, Collection<String> dontSkipInstallForComponents, boolean skipFailure) {
@@ -562,7 +583,7 @@ public class AmbariContext {
/**
* Add the new host to an existing config group.
*/
- private boolean addHostToExistingConfigGroups(String hostName, ClusterTopology topology, String groupName) {
+ private boolean addHostToExistingConfigGroups(String hostName, ClusterTopology topology, String configGroupName) {
boolean addedHost = false;
Clusters clusters;
Cluster cluster;
@@ -576,9 +597,8 @@ public class AmbariContext {
// I don't know of a method to get config group by name
//todo: add a method to get config group by name
Map<Long, ConfigGroup> configGroups = cluster.getConfigGroups();
- String qualifiedGroupName = getConfigurationGroupName(topology.getBlueprint().getName(), groupName);
for (ConfigGroup group : configGroups.values()) {
- if (group.getName().equals(qualifiedGroupName)) {
+ if (group.getName().equals(configGroupName)) {
try {
Host host = clusters.getHost(hostName);
addedHost = true;