You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2016/06/13 08:38:31 UTC
[2/3] brooklyn-library git commit: AbstractGeoDnsServiceImpl uses own
lock to guard tracker
AbstractGeoDnsServiceImpl uses own lock to guard tracker
Otherwise a deadlock is possible by -
Thread A:
Geoscaling.startTracker is synchronized on the entity
Calls config.get(CONFIG_KEY)
Dependent value set for config key
Brooklyn starts Thread B to resolve value.
Thread B:
Tries to get AbstractEntity.getExecutionContext,
which is also a method synchronized on the entity.
Blocks forever
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-library/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-library/commit/2e1246a8
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-library/tree/2e1246a8
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-library/diff/2e1246a8
Branch: refs/heads/master
Commit: 2e1246a8714422b21ab0262192837f6d31fd086b
Parents: afbf8f1
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Wed May 18 17:46:43 2016 +0100
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Wed May 18 17:46:43 2016 +0100
----------------------------------------------------------------------
.../entity/dns/AbstractGeoDnsServiceImpl.java | 62 ++++++++++++--------
1 file changed, 39 insertions(+), 23 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/2e1246a8/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java
index 65e4291..843673f 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java
@@ -46,14 +46,14 @@ import org.apache.brooklyn.core.location.geo.HostGeoInfo;
import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy;
import org.apache.brooklyn.entity.group.DynamicGroup;
import org.apache.brooklyn.entity.webapp.WebAppService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.net.Networking;
import org.apache.brooklyn.util.time.Duration;
import org.apache.brooklyn.util.time.Time;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
@@ -65,6 +65,8 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement
@SetFromFlag
protected Group targetEntityProvider;
protected AbstractMembershipTrackingPolicy tracker;
+ /** Guards access to {@link #tracker}. */
+ protected final Object trackerLock = new Object[0];
protected Map<Entity, HostGeoInfo> targetHosts = Collections.synchronizedMap(new LinkedHashMap<Entity, HostGeoInfo>());
@@ -134,31 +136,45 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement
/** should set up so these hosts are targeted, and setServiceState appropriately */
protected abstract void reconfigureService(Collection<HostGeoInfo> targetHosts);
- protected synchronized void startTracker() {
- if (targetEntityProvider==null || !getManagementSupport().isDeployed()) {
- log.debug("Tracker for "+this+" not yet active: "+targetEntityProvider+" / "+getManagementContext());
- return;
- }
- endTracker();
+ /**
+ * Start the tracker.
+ * <p>
+ * Subclasses should take care to synchronize on {@link #trackerLock}.
+ */
+ protected void startTracker() {
+ synchronized (trackerLock) {
+ if (targetEntityProvider == null || !getManagementSupport().isDeployed()) {
+ log.debug("Tracker for " + this + " not yet active: " + targetEntityProvider + " / " + getManagementContext());
+ return;
+ }
+ endTracker();
- ImmutableSet.Builder<Sensor<?>> sensorsToTrack = ImmutableSet.<Sensor<?>>builder().add(
- HOSTNAME, ADDRESS, Attributes.MAIN_URI, WebAppService.ROOT_URL);
- // Don't subscribe to lifecycle events if entities will be included regardless of their status.
- if (Boolean.TRUE.equals(config().get(FILTER_FOR_RUNNING))) {
- sensorsToTrack.add(Attributes.SERVICE_STATE_ACTUAL);
+ ImmutableSet.Builder<Sensor<?>> sensorsToTrack = ImmutableSet.<Sensor<?>>builder().add(
+ HOSTNAME, ADDRESS, Attributes.MAIN_URI, WebAppService.ROOT_URL);
+ // Don't subscribe to lifecycle events if entities will be included regardless of their status.
+ if (Boolean.TRUE.equals(config().get(FILTER_FOR_RUNNING))) {
+ sensorsToTrack.add(Attributes.SERVICE_STATE_ACTUAL);
+ }
+ log.debug("Initializing tracker for " + this + ", following " + targetEntityProvider);
+ tracker = policies().add(PolicySpec.create(MemberTrackingPolicy.class)
+ .displayName("GeoDNS targets tracker")
+ .configure(AbstractMembershipTrackingPolicy.SENSORS_TO_TRACK, sensorsToTrack.build())
+ .configure(AbstractMembershipTrackingPolicy.GROUP, targetEntityProvider));
+ refreshGroupMembership();
}
- log.debug("Initializing tracker for "+this+", following "+targetEntityProvider);
- tracker = policies().add(PolicySpec.create(MemberTrackingPolicy.class)
- .displayName("GeoDNS targets tracker")
- .configure(AbstractMembershipTrackingPolicy.SENSORS_TO_TRACK, sensorsToTrack.build())
- .configure(AbstractMembershipTrackingPolicy.GROUP, targetEntityProvider));
- refreshGroupMembership();
}
- protected synchronized void endTracker() {
- if (tracker == null || targetEntityProvider==null) return;
- policies().remove(tracker);
- tracker = null;
+ /**
+ * End the tracker.
+ * <p>
+ * Subclasses should take care to synchronize on {@link #trackerLock}.
+ */
+ protected void endTracker() {
+ synchronized (trackerLock) {
+ if (tracker == null || targetEntityProvider == null) return;
+ policies().remove(tracker);
+ tracker = null;
+ }
}
public static class MemberTrackingPolicy extends AbstractMembershipTrackingPolicy {