You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2015/12/01 23:22:06 UTC
[42/50] [abbrv] incubator-geode git commit: GEODE-616: failure
detection ports not set in new membership view
GEODE-616: failure detection ports not set in new membership view
Added a method to NetView to copy failure detection ports from an old
view to the new view. I also added a JUnit test for NetView to make
sure we have adequate code-coverage for this class.
Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/e4448adc
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/e4448adc
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/e4448adc
Branch: refs/heads/feature/GEODE-291
Commit: e4448adc3ce1c5774410194dcbd361eb21890e7d
Parents: 2803a10
Author: Bruce Schuchardt <bs...@pivotal.io>
Authored: Tue Dec 1 08:33:02 2015 -0800
Committer: Bruce Schuchardt <bs...@pivotal.io>
Committed: Tue Dec 1 08:33:02 2015 -0800
----------------------------------------------------------------------
.../internal/membership/NetView.java | 46 ++++-
.../membership/gms/membership/GMSJoinLeave.java | 25 +--
.../internal/membership/NetViewJUnitTest.java | 194 +++++++++++++++++++
3 files changed, 241 insertions(+), 24 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/e4448adc/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/NetView.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/NetView.java b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/NetView.java
index 8800d9d..a90a45d 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/NetView.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/NetView.java
@@ -88,6 +88,12 @@ public class NetView implements DataSerializableFixedID {
Arrays.fill(failureDetectionPorts, -1);
}
+ /**
+ * Create a new view with the contents of the given view and the
+ * specified view ID
+ * @param other
+ * @param viewId
+ */
public NetView(NetView other, int viewId) {
this.creator = other.creator;
this.viewId = viewId;
@@ -129,7 +135,7 @@ public class NetView implements DataSerializableFixedID {
public int getFailureDetectionPort(InternalDistributedMember mbr) {
int idx = members.indexOf(mbr);
- if (idx < 0 || failureDetectionPorts == null || idx >= failureDetectionPorts.length) {
+ if (idx < 0 || idx >= failureDetectionPorts.length) {
return -1;
}
return failureDetectionPorts[idx];
@@ -143,15 +149,36 @@ public class NetView implements DataSerializableFixedID {
ensureFDCapacity(idx);
failureDetectionPorts[idx] = port;
}
+
+ /**
+ * Transfer the failure-detection ports from another view to this one
+ * @param otherView
+ */
+ public void setFailureDetectionPorts(NetView otherView) {
+ int[] ports = otherView.getFailureDetectionPorts();
+ if (ports != null) {
+ int idx = 0;
+ int portsSize = ports.length;
+ for (InternalDistributedMember mbr: otherView.getMembers()) {
+ if (contains(mbr)) {
+ // unit tests create views w/o failure detection ports, so we must check the length
+ // of the array
+ if (idx < portsSize) {
+ setFailureDetectionPort(mbr, ports[idx]);
+ } else {
+ setFailureDetectionPort(mbr, -1);
+ }
+ }
+ idx += 1;
+ }
+ }
+ }
/**
* ensures that there is a slot at idx to store an int
*/
private void ensureFDCapacity(int idx) {
- if (failureDetectionPorts == null) {
- failureDetectionPorts = new int[idx+10];
- Arrays.fill(failureDetectionPorts, -1);
- } else if (idx >= failureDetectionPorts.length) {
+ if (idx >= failureDetectionPorts.length) {
int[] p = new int[idx+10];
if (failureDetectionPorts.length > 0) {
System.arraycopy(failureDetectionPorts, 0, p, 0, failureDetectionPorts.length);
@@ -479,6 +506,15 @@ public class NetView implements DataSerializableFixedID {
first = false;
}
}
+// sb.append("] fd ports: [");
+// int[] ports = getFailureDetectionPorts();
+// int numMembers = size();
+// for (int i=0; i<numMembers; i++) {
+// if (i > 0) {
+// sb.append(' ');
+// }
+// sb.append(ports[i]);
+// }
sb.append("]");
return sb.toString();
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/e4448adc/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
index 1c7b601..2f8d734 100755
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/membership/GMSJoinLeave.java
@@ -531,7 +531,6 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
NetView check = new NetView(v, v.getViewId() + 1);
synchronized (removedMembers) {
removedMembers.add(mbr);
- check = new NetView(v, v.getViewId());
check.addCrashedMembers(removedMembers);
check.removeAll(removedMembers);
}
@@ -660,6 +659,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
mbrs.removeAll(leaving);
newView = new NetView(this.localAddress, viewNumber, mbrs, leaving,
removals);
+ newView.setFailureDetectionPorts(currentView);
newView.setFailureDetectionPort(this.localAddress, services.getHealthMonitor().getFailureDetectionPort());
}
if (viewCreator == null || viewCreator.isShutdown()) {
@@ -1890,23 +1890,7 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
}
}
if (currentView != null) {
- int[] ports = currentView.getFailureDetectionPorts();
- if (ports != null) {
- int idx = 0;
- int portsSize = ports.length;
- for (InternalDistributedMember mbr: currentView.getMembers()) {
- if (newView.contains(mbr)) {
- // unit tests create views w/o failure detection ports, so we must check the length
- // of the array
- if (idx < portsSize) {
- newView.setFailureDetectionPort(mbr, ports[idx]);
- } else {
- newView.setFailureDetectionPort(mbr, -1);
- }
- }
- idx += 1;
- }
- }
+ newView.setFailureDetectionPorts(currentView);
}
}
@@ -1995,12 +1979,15 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler {
logger.info("adding these new members from a conflicting view to the new view: {}", newMembers);
for (InternalDistributedMember mbr: newMembers) {
int port = conflictingView.getFailureDetectionPort(mbr);
- JoinRequestMessage msg = new JoinRequestMessage(localAddress, mbr, null, port);
newView.add(mbr);
newView.setFailureDetectionPort(mbr, port);
joinReqs.add(mbr);
}
}
+ // trump the view ID of the conflicting view so mine will be accepted
+ if (conflictingView.getViewId() >= newView.getViewId()) {
+ newView = new NetView(newView, conflictingView.getViewId()+1);
+ }
}
if (!unresponsive.isEmpty()) {
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/e4448adc/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/NetViewJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/NetViewJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/NetViewJUnitTest.java
new file mode 100755
index 0000000..603c7bf
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/distributed/internal/membership/NetViewJUnitTest.java
@@ -0,0 +1,194 @@
+package com.gemstone.gemfire.distributed.internal.membership;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.Timer;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import com.gemstone.gemfire.distributed.internal.DistributionManager;
+import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+import com.gemstone.gemfire.distributed.internal.membership.NetView;
+import com.gemstone.gemfire.internal.SocketCreator;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+
+@Category(UnitTest.class)
+public class NetViewJUnitTest {
+ List<InternalDistributedMember> members;
+
+ @Before
+ public void initMembers() throws Exception {
+ int numMembers = 10;
+ members = new ArrayList<>(numMembers);
+ for (int i=0; i<numMembers; i++) {
+ members.add(new InternalDistributedMember(SocketCreator.getLocalHost(), 1000+i));
+ }
+ // view creator is a locator
+ members.get(0).setVmKind(DistributionManager.LOCATOR_DM_TYPE);
+ members.get(0).setVmViewId(0);
+ members.get(0).getNetMember().setPreferredForCoordinator(true);
+
+ // members who joined in view #1
+ for (int i=1; i<(numMembers-1); i++) {
+ members.get(i).setVmViewId(1);
+ members.get(i).setVmKind(DistributionManager.NORMAL_DM_TYPE);
+ members.get(i).getNetMember().setPreferredForCoordinator(false);
+ }
+
+ // member joining in this view
+ members.get(numMembers-1).setVmViewId(2);
+ members.get(numMembers-1).setVmKind(DistributionManager.NORMAL_DM_TYPE);
+ }
+
+ private void setFailureDetectionPorts(NetView view) {
+ int numMembers = members.size();
+ // use the membership port as the FD port so it's easy to figure out problems
+ for (int i=0; i<numMembers; i++) {
+ view.setFailureDetectionPort(members.get(i), members.get(i).getPort());
+ }
+ }
+
+ @Test
+ public void testCreateView() throws Exception {
+ int numMembers = members.size();
+ NetView view = new NetView(members.get(0), 2, members, Collections.emptySet(), Collections.emptySet());
+ setFailureDetectionPorts(view);
+
+ assertTrue(view.getCreator().equals(members.get(0)));
+ assertEquals(2, view.getViewId());
+ assertEquals(members, view.getMembers());
+ assertEquals(0, view.getCrashedMembers().size());
+ assertEquals(members.get(1), view.getLeadMember()); // a locator can't be lead member
+ assertEquals(0, view.getShutdownMembers().size());
+ assertEquals(1, view.getNewMembers().size());
+ assertEquals(members.get(numMembers-1), view.getNewMembers().iterator().next());
+ assertEquals(members.get(0), view.getCoordinator());
+
+ for (int i=0; i<numMembers; i++) {
+ InternalDistributedMember mbr = members.get(i);
+ assertEquals(mbr.getPort(), view.getFailureDetectionPort(mbr));
+ }
+
+ assertFalse(view.shouldBeCoordinator(members.get(1)));
+ assertTrue(view.shouldBeCoordinator(members.get(0)));
+ assertEquals(members.get(numMembers-1), view.getCoordinator(Collections.singletonList(members.get(0))));
+ members.get(numMembers-1).getNetMember().setPreferredForCoordinator(false);
+ assertEquals(members.get(1), view.getCoordinator(Collections.singletonList(members.get(0))));
+
+ members.get(numMembers-1).getNetMember().setPreferredForCoordinator(true);
+ List<InternalDistributedMember> preferred = view.getPreferredCoordinators(Collections.<InternalDistributedMember>singleton(members.get(1)), members.get(0), 2);
+ assertEquals(3, preferred.size());
+ assertEquals(members.get(numMembers-1), preferred.get(0));
+ }
+
+ @Test
+ public void testRemoveMembers() throws Exception {
+ int numMembers = members.size();
+ NetView view = new NetView(members.get(0), 2, new ArrayList<>(members), Collections.emptySet(),
+ Collections.emptySet());
+ setFailureDetectionPorts(view);
+
+ for (int i=1; i<numMembers; i+=2) {
+ view.remove(members.get(i));
+ assertFalse(view.contains(members.get(i)));
+ }
+
+ List<InternalDistributedMember> remainingMembers = view.getMembers();
+ int num = remainingMembers.size();
+ for (int i=0; i<num; i++) {
+ InternalDistributedMember mbr = remainingMembers.get(i);
+ assertEquals(mbr.getPort(), view.getFailureDetectionPort(mbr));
+ }
+ }
+
+ @Test
+ public void testRemoveAll() throws Exception {
+ int numMembers = members.size();
+ NetView view = new NetView(members.get(0), 2, new ArrayList<>(members), Collections.emptySet(),
+ Collections.emptySet());
+ setFailureDetectionPorts(view);
+
+ Collection<InternalDistributedMember> removals = new ArrayList<>(numMembers/2);
+ for (int i=1; i<numMembers; i+=2) {
+ removals.add(members.get(i));
+ }
+
+ view.removeAll(removals);
+ for (InternalDistributedMember mbr: removals) {
+ assertFalse(view.contains(mbr));
+ }
+ assertEquals(numMembers-removals.size(), view.size());
+
+ List<InternalDistributedMember> remainingMembers = view.getMembers();
+ int num = remainingMembers.size();
+ for (int i=0; i<num; i++) {
+ InternalDistributedMember mbr = remainingMembers.get(i);
+ assertEquals(mbr.getPort(), view.getFailureDetectionPort(mbr));
+ }
+ }
+
+ @Test
+ public void testCopyView() throws Exception {
+ NetView view = new NetView(members.get(0), 2, new ArrayList<>(members), Collections.emptySet(),
+ Collections.emptySet());
+ setFailureDetectionPorts(view);
+
+ NetView newView = new NetView(view, 3);
+
+ assertTrue(newView.getCreator().equals(members.get(0)));
+ assertEquals(3, newView.getViewId());
+ assertEquals(members, newView.getMembers());
+ assertEquals(0, newView.getCrashedMembers().size());
+ assertEquals(members.get(1), newView.getLeadMember()); // a locator can't be lead member
+ assertEquals(0, newView.getShutdownMembers().size());
+ assertEquals(0, newView.getNewMembers().size());
+ assertTrue(newView.equals(view));
+ assertTrue(view.equals(newView));
+ newView.remove(members.get(1));
+ assertFalse(newView.equals(view));
+ }
+
+ @Test
+ public void testAddLotsOfMembers() throws Exception {
+ NetView view = new NetView(members.get(0), 2, new ArrayList<>(members), Collections.emptySet(),
+ Collections.emptySet());
+ setFailureDetectionPorts(view);
+
+ NetView copy = new NetView(view, 2);
+
+ int oldSize = view.size();
+ for (int i=0; i<100; i++) {
+ InternalDistributedMember mbr = new InternalDistributedMember(SocketCreator.getLocalHost(), 2000+i);
+ mbr.setVmKind(DistributionManager.NORMAL_DM_TYPE);
+ mbr.setVmViewId(2);
+ view.add(mbr);
+ view.setFailureDetectionPort(mbr, 2000+i);
+ }
+
+ assertEquals(oldSize+100, view.size());
+ for (InternalDistributedMember mbr: view.getMembers()) {
+ assertEquals(mbr.getPort(), view.getFailureDetectionPort(mbr));
+ }
+
+ assertEquals(100, view.getNewMembers(copy).size());
+ }
+
+}