Bug 7814: Fix InvalidActorNameException 90/53190/1
authorTom Pantelis <tpanteli@brocade.com>
Fri, 10 Mar 2017 23:03:11 +0000 (18:03 -0500)
committerTom Pantelis <tpanteli@brocade.com>
Sun, 12 Mar 2017 05:26:48 +0000 (00:26 -0500)
When a read tx actor is created in the Shard, the actor name is generated
as eg "shard-member-1:datastore-operational@0:19" where 0 is the instance's
static generation id and 19 is the tx id. If the tx was created from a chain,
the chain's history id is appended. So every part of the name is constant for
the controller instance except the tx id, which is generated via a counter in
AbstractTransactionContextFactory, and the history id which is also generated
via a counter. The counters do make the full tx id unique in the cluster.
However if multiple shards are involved in a single front-end transaction,
they all have the same tx id and thus the actor names generated by each shard
would be the same. It seems that's what occurred in Bug 7814. Therefore I
changed the actor name to include the shard name.

Change-Id: Iacb11bb401bd6bded38847690f8009c115ee0637
Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/Shard.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardTransactionFactory.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTest.java

index c6f05ca70e7e857c1d0b84d0d095cbcf368e71e6..dfd174010b5a795840d501858ea92d3c91c89382 100644 (file)
@@ -176,8 +176,8 @@ public class Shard extends RaftActor {
                 getRaftActorContext().getConfigParams().getIsolatedCheckIntervalInMillis());
 
         transactionActorFactory = new ShardTransactionActorFactory(store, datastoreContext,
-                new Dispatchers(context().system().dispatchers()).getDispatcherPath(
-                        Dispatchers.DispatcherType.Transaction), self(), getContext(), shardMBean);
+            new Dispatchers(context().system().dispatchers()).getDispatcherPath(Dispatchers.DispatcherType.Transaction),
+                self(), getContext(), shardMBean, builder.getId().getShardName());
 
         snapshotCohort = ShardSnapshotCohort.create(getContext(), builder.getId().getMemberName(), store, LOG,
             this.name);
index ecfd2aa50d8375ac3cc184eaf1e55a383bc85df5..d21878f95d613e724deafd6ae9af9452ccd68f57 100644 (file)
@@ -29,26 +29,30 @@ class ShardTransactionActorFactory {
     private final ShardStats shardMBean;
     private final UntypedActorContext actorContext;
     private final ActorRef shardActor;
+    private final String shardName;
 
     ShardTransactionActorFactory(ShardDataTree dataTree, DatastoreContext datastoreContext,
-            String txnDispatcherPath, ActorRef shardActor, UntypedActorContext actorContext, ShardStats shardMBean) {
+            String txnDispatcherPath, ActorRef shardActor, UntypedActorContext actorContext, ShardStats shardMBean,
+            String shardName) {
         this.dataTree = Preconditions.checkNotNull(dataTree);
-        this.datastoreContext = datastoreContext;
-        this.txnDispatcherPath = txnDispatcherPath;
-        this.shardMBean = shardMBean;
-        this.actorContext = actorContext;
-        this.shardActor = shardActor;
+        this.datastoreContext = Preconditions.checkNotNull(datastoreContext);
+        this.txnDispatcherPath = Preconditions.checkNotNull(txnDispatcherPath);
+        this.shardMBean = Preconditions.checkNotNull(shardMBean);
+        this.actorContext = Preconditions.checkNotNull(actorContext);
+        this.shardActor = Preconditions.checkNotNull(shardActor);
+        this.shardName = Preconditions.checkNotNull(shardName);
     }
 
-    private static String actorNameFor(final TransactionIdentifier txId) {
+    private String actorNameFor(final TransactionIdentifier txId) {
         final LocalHistoryIdentifier historyId = txId.getHistoryId();
         final ClientIdentifier clientId = historyId.getClientId();
         final FrontendIdentifier frontendId = clientId.getFrontendId();
 
         final StringBuilder sb = new StringBuilder("shard-");
-        sb.append(frontendId.getMemberName().getName()).append(':');
-        sb.append(frontendId.getClientType().getName()).append('@');
-        sb.append(clientId.getGeneration()).append(':');
+        sb.append(shardName).append('-')
+            .append(frontendId.getMemberName().getName()).append(':')
+            .append(frontendId.getClientType().getName()).append('@')
+            .append(clientId.getGeneration()).append(':');
         if (historyId.getHistoryId() != 0) {
             sb.append(historyId.getHistoryId()).append('-');
         }
index 5c4e35a3a99d60095d6f0e2a6f08d4b81aed350c..83d756322e95cce6c747d251f41184e3ab932102 100644 (file)
@@ -364,8 +364,9 @@ public class ShardTest extends AbstractShardTest {
                     CreateTransactionReply.class);
 
             final String path = reply.getTransactionPath().toString();
-            assertTrue("Unexpected transaction path " + path,
-                    path.startsWith("akka://test/user/testCreateTransaction/shard-member-1:ShardTransactionTest@0:"));
+            assertTrue("Unexpected transaction path " + path, path.startsWith(String.format(
+                    "akka://test/user/testCreateTransaction/shard-%s-%s:ShardTransactionTest@0:",
+                        shardID.getShardName(), shardID.getMemberName().getName())));
         }};
     }
 
@@ -383,8 +384,9 @@ public class ShardTest extends AbstractShardTest {
                     CreateTransactionReply.class);
 
             final String path = reply.getTransactionPath().toString();
-            assertTrue("Unexpected transaction path " + path,
-                    path.startsWith("akka://test/user/testCreateTransactionOnChain/shard-member-1:ShardTransactionTest@0:"));
+            assertTrue("Unexpected transaction path " + path, path.startsWith(String.format(
+                    "akka://test/user/testCreateTransactionOnChain/shard-%s-%s:ShardTransactionTest@0:",
+                    shardID.getShardName(), shardID.getMemberName().getName())));
         }};
     }