Do not retain initial SchemaContext
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / shardmanager / ShardInformation.java
index a37a94fd0ec860cbb2de342c3f144d627b6b8cf7..8fc77acf96395f58cfe1d919a1fd3e8a598eba38 100644 (file)
@@ -10,15 +10,16 @@ package org.opendaylight.controller.cluster.datastore.shardmanager;
 import akka.actor.ActorRef;
 import akka.actor.Props;
 import akka.serialization.Serialization;
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 import javax.annotation.Nullable;
+import org.opendaylight.controller.cluster.access.concepts.MemberName;
 import org.opendaylight.controller.cluster.datastore.DatastoreContext;
 import org.opendaylight.controller.cluster.datastore.Shard;
 import org.opendaylight.controller.cluster.datastore.identifiers.ShardIdentifier;
@@ -41,7 +42,13 @@ final class ShardInformation {
     private final ShardPeerAddressResolver addressResolver;
     private final ShardIdentifier shardId;
     private final String shardName;
+
+    // This reference indirection is required to have the ability to update the SchemaContext
+    // inside actor props. Otherwise we would be keeping an old SchemaContext there, preventing
+    // it from becoming garbage.
+    private final AtomicShardContextProvider schemaContextProvider = new AtomicShardContextProvider();
     private ActorRef actor;
+
     private Optional<DataTree> localShardDataTree;
     private boolean leaderAvailable = false;
 
@@ -58,9 +65,9 @@ final class ShardInformation {
     private Shard.AbstractBuilder<?, ?> builder;
     private boolean isActiveMember = true;
 
-    ShardInformation(String shardName, ShardIdentifier shardId,
-            Map<String, String> initialPeerAddresses, DatastoreContext datastoreContext,
-            Shard.AbstractBuilder<?, ?> builder, ShardPeerAddressResolver addressResolver) {
+    ShardInformation(final String shardName, final ShardIdentifier shardId,
+            final Map<String, String> initialPeerAddresses, final DatastoreContext datastoreContext,
+            final Shard.AbstractBuilder<?, ?> builder, final ShardPeerAddressResolver addressResolver) {
         this.shardName = shardName;
         this.shardId = shardId;
         this.initialPeerAddresses = initialPeerAddresses;
@@ -69,10 +76,10 @@ final class ShardInformation {
         this.addressResolver = addressResolver;
     }
 
-    Props newProps(SchemaContext schemaContext) {
+    Props newProps() {
         Preconditions.checkNotNull(builder);
-        Props props = builder.id(shardId).peerAddresses(initialPeerAddresses).datastoreContext(datastoreContext).
-                schemaContext(schemaContext).props();
+        Props props = builder.id(shardId).peerAddresses(initialPeerAddresses).datastoreContext(datastoreContext)
+                .schemaContextProvider(schemaContextProvider).props();
         builder = null;
         return props;
     }
@@ -82,11 +89,11 @@ final class ShardInformation {
     }
 
     @Nullable
-    ActorRef getActor(){
+    ActorRef getActor() {
         return actor;
     }
 
-    void setActor(ActorRef actor) {
+    void setActor(final ActorRef actor) {
         this.actor = actor;
     }
 
@@ -94,7 +101,7 @@ final class ShardInformation {
         return shardId;
     }
 
-    void setLocalDataTree(Optional<DataTree> localShardDataTree) {
+    void setLocalDataTree(final Optional<DataTree> localShardDataTree) {
         this.localShardDataTree = localShardDataTree;
     }
 
@@ -106,7 +113,7 @@ final class ShardInformation {
         return datastoreContext;
     }
 
-    void setDatastoreContext(DatastoreContext datastoreContext, ActorRef sender) {
+    void setDatastoreContext(final DatastoreContext datastoreContext, final ActorRef sender) {
         this.datastoreContext = datastoreContext;
         if (actor != null) {
             LOG.debug("Sending new DatastoreContext to {}", shardId);
@@ -114,14 +121,12 @@ final class ShardInformation {
         }
     }
 
-    void updatePeerAddress(String peerId, String peerAddress, ActorRef sender){
+    void updatePeerAddress(final String peerId, final String peerAddress, final ActorRef sender) {
         LOG.info("updatePeerAddress for peer {} with address {}", peerId, peerAddress);
 
-        if(actor != null) {
-            if(LOG.isDebugEnabled()) {
-                LOG.debug("Sending PeerAddressResolved for peer {} with address {} to {}",
-                        peerId, peerAddress, actor.path());
-            }
+        if (actor != null) {
+            LOG.debug("Sending PeerAddressResolved for peer {} with address {} to {}", peerId,
+                    peerAddress, actor.path());
 
             actor.tell(new PeerAddressResolved(peerId, peerAddress), sender);
         }
@@ -129,14 +134,14 @@ final class ShardInformation {
         notifyOnShardInitializedCallbacks();
     }
 
-    void peerDown(String memberName, String peerId, ActorRef sender) {
-        if(actor != null) {
+    void peerDown(final MemberName memberName, final String peerId, final ActorRef sender) {
+        if (actor != null) {
             actor.tell(new PeerDown(memberName, peerId), sender);
         }
     }
 
-    void peerUp(String memberName, String peerId, ActorRef sender) {
-        if(actor != null) {
+    void peerUp(final MemberName memberName, final String peerId, final ActorRef sender) {
+        if (actor != null) {
             actor.tell(new PeerUp(memberName, peerId), sender);
         }
     }
@@ -146,8 +151,9 @@ final class ShardInformation {
     }
 
     boolean isShardReadyWithLeaderId() {
-        return leaderAvailable && isShardReady() && !RaftState.IsolatedLeader.name().equals(role) &&
-                (isLeader() || addressResolver.resolve(leaderId) != null);
+        return leaderAvailable && isShardReady() && !RaftState.IsolatedLeader.name().equals(role)
+                && !RaftState.PreLeader.name().equals(role)
+                && (isLeader() || addressResolver.resolve(leaderId) != null);
     }
 
     boolean isShardInitialized() {
@@ -155,11 +161,11 @@ final class ShardInformation {
     }
 
     boolean isLeader() {
-        return Objects.equal(leaderId, shardId.toString());
+        return Objects.equals(leaderId, shardId.toString());
     }
 
     String getSerializedLeaderActor() {
-        if(isLeader()) {
+        if (isLeader()) {
             return Serialization.serializedActorPath(getActor());
         } else {
             return addressResolver.resolve(leaderId);
@@ -175,7 +181,7 @@ final class ShardInformation {
     }
 
     private void notifyOnShardInitializedCallbacks() {
-        if(onShardInitializedSet.isEmpty()) {
+        if (onShardInitializedSet.isEmpty()) {
             return;
         }
 
@@ -185,7 +191,7 @@ final class ShardInformation {
             ready ? "ready" : "initialized", onShardInitializedSet.size());
 
         Iterator<OnShardInitialized> iter = onShardInitializedSet.iterator();
-        while(iter.hasNext()) {
+        while (iter.hasNext()) {
             OnShardInitialized onShardInitialized = iter.next();
             if (!(onShardInitialized instanceof OnShardReady) || ready) {
                 iter.remove();
@@ -195,38 +201,42 @@ final class ShardInformation {
         }
     }
 
-    void addOnShardInitialized(OnShardInitialized onShardInitialized) {
+    void addOnShardInitialized(final OnShardInitialized onShardInitialized) {
         onShardInitializedSet.add(onShardInitialized);
     }
 
-    void removeOnShardInitialized(OnShardInitialized onShardInitialized) {
+    void removeOnShardInitialized(final OnShardInitialized onShardInitialized) {
         onShardInitializedSet.remove(onShardInitialized);
     }
 
-    void setRole(String newRole) {
+    void setRole(final String newRole) {
         this.role = newRole;
 
         notifyOnShardInitializedCallbacks();
     }
 
-    void setFollowerSyncStatus(boolean syncStatus){
+    String getRole() {
+        return role;
+    }
+
+    void setFollowerSyncStatus(final boolean syncStatus) {
         this.followerSyncStatus = syncStatus;
     }
 
-    boolean isInSync(){
-        if(RaftState.Follower.name().equals(this.role)){
+    boolean isInSync() {
+        if (RaftState.Follower.name().equals(this.role)) {
             return followerSyncStatus;
-        } else if(RaftState.Leader.name().equals(this.role)){
+        } else if (RaftState.Leader.name().equals(this.role)) {
             return true;
         }
 
         return false;
     }
 
-    boolean setLeaderId(String leaderId) {
-        boolean changed = !Objects.equal(this.leaderId, leaderId);
+    boolean setLeaderId(final String leaderId) {
+        final boolean changed = !Objects.equals(this.leaderId, leaderId);
         this.leaderId = leaderId;
-        if(leaderId != null) {
+        if (leaderId != null) {
             this.leaderAvailable = true;
         }
         notifyOnShardInitializedCallbacks();
@@ -238,10 +248,10 @@ final class ShardInformation {
         return leaderId;
     }
 
-    void setLeaderAvailable(boolean leaderAvailable) {
+    void setLeaderAvailable(final boolean leaderAvailable) {
         this.leaderAvailable = leaderAvailable;
 
-        if(leaderAvailable) {
+        if (leaderAvailable) {
             notifyOnShardInitializedCallbacks();
         }
     }
@@ -250,7 +260,7 @@ final class ShardInformation {
         return leaderVersion;
     }
 
-    void setLeaderVersion(short leaderVersion) {
+    void setLeaderVersion(final short leaderVersion) {
         this.leaderVersion = leaderVersion;
     }
 
@@ -258,7 +268,15 @@ final class ShardInformation {
         return isActiveMember;
     }
 
-    void setActiveMember(boolean isActiveMember) {
+    void setActiveMember(final boolean isActiveMember) {
         this.isActiveMember = isActiveMember;
     }
-}
\ No newline at end of file
+
+    SchemaContext getSchemaContext() {
+        return schemaContextProvider.getSchemaContext();
+    }
+
+    void setSchemaContext(final SchemaContext schemaContext) {
+        schemaContextProvider.set(Preconditions.checkNotNull(schemaContext));
+    }
+}