fixes related to getRole() assumptions
Change-Id: Icf19d95714dc217200eed021a495d9a78440ca8e
Showing
5 changed files
with
40 additions
and
63 deletions
| 1 | package org.onlab.onos.mastership; | 1 | package org.onlab.onos.mastership; |
| 2 | 2 | ||
| 3 | -import org.onlab.onos.cluster.NodeId; | ||
| 4 | import org.onlab.onos.cluster.RoleInfo; | 3 | import org.onlab.onos.cluster.RoleInfo; |
| 5 | import org.onlab.onos.event.AbstractEvent; | 4 | import org.onlab.onos.event.AbstractEvent; |
| 6 | import org.onlab.onos.net.DeviceId; | 5 | import org.onlab.onos.net.DeviceId; |
| ... | @@ -56,19 +55,6 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI | ... | @@ -56,19 +55,6 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI |
| 56 | } | 55 | } |
| 57 | 56 | ||
| 58 | /** | 57 | /** |
| 59 | - * Returns the NodeID of the node associated with the event. | ||
| 60 | - * For MASTER_CHANGED this is the newly elected master, and for | ||
| 61 | - * BACKUPS_CHANGED, this is the node that was newly added, removed, or | ||
| 62 | - * whose position was changed in the list. | ||
| 63 | - * | ||
| 64 | - * @return node ID as a subject | ||
| 65 | - */ | ||
| 66 | - //XXX to-be removed - or keep for convenience? | ||
| 67 | - public NodeId node() { | ||
| 68 | - return roleInfo.master(); | ||
| 69 | - } | ||
| 70 | - | ||
| 71 | - /** | ||
| 72 | * Returns the current role state for the subject. | 58 | * Returns the current role state for the subject. |
| 73 | * | 59 | * |
| 74 | * @return RoleInfo associated with Device ID subject | 60 | * @return RoleInfo associated with Device ID subject | ... | ... |
| ... | @@ -227,10 +227,14 @@ implements MastershipService, MastershipAdminService { | ... | @@ -227,10 +227,14 @@ implements MastershipService, MastershipAdminService { |
| 227 | if (clusterService.getNodes().size() > (clusterSize.intValue() / 2)) { | 227 | if (clusterService.getNodes().size() > (clusterSize.intValue() / 2)) { |
| 228 | return true; | 228 | return true; |
| 229 | } | 229 | } |
| 230 | - //else { | 230 | +// else { |
| 231 | //FIXME: break tie for equal-sized clusters, by number of | 231 | //FIXME: break tie for equal-sized clusters, by number of |
| 232 | // connected switches, then masters, then nodeId hash | 232 | // connected switches, then masters, then nodeId hash |
| 233 | - // } | 233 | + // problem is, how do we get at channel info cleanly here? |
| 234 | + // Also, what's the time hit for a distributed store look-up | ||
| 235 | + // versus channel re-negotiation? bet on the latter being worse. | ||
| 236 | + | ||
| 237 | +// } | ||
| 234 | return false; | 238 | return false; |
| 235 | } | 239 | } |
| 236 | 240 | ... | ... |
| ... | @@ -86,7 +86,7 @@ public class ReplicaInfoManager implements ReplicaInfoService { | ... | @@ -86,7 +86,7 @@ public class ReplicaInfoManager implements ReplicaInfoService { |
| 86 | final List<NodeId> standbyList = Collections.<NodeId>emptyList(); | 86 | final List<NodeId> standbyList = Collections.<NodeId>emptyList(); |
| 87 | eventDispatcher.post(new ReplicaInfoEvent(MASTER_CHANGED, | 87 | eventDispatcher.post(new ReplicaInfoEvent(MASTER_CHANGED, |
| 88 | event.subject(), | 88 | event.subject(), |
| 89 | - new ReplicaInfo(event.node(), standbyList))); | 89 | + new ReplicaInfo(event.roleInfo().master(), standbyList))); |
| 90 | } | 90 | } |
| 91 | } | 91 | } |
| 92 | 92 | ... | ... |
| ... | @@ -91,23 +91,14 @@ implements MastershipStore { | ... | @@ -91,23 +91,14 @@ implements MastershipStore { |
| 91 | 91 | ||
| 92 | @Override | 92 | @Override |
| 93 | public MastershipRole getRole(NodeId nodeId, DeviceId deviceId) { | 93 | public MastershipRole getRole(NodeId nodeId, DeviceId deviceId) { |
| 94 | - NodeId current = getNode(MASTER, deviceId); | 94 | + final RoleValue roleInfo = getRoleValue(deviceId); |
| 95 | - if (current == null) { | 95 | + if (roleInfo.contains(MASTER, nodeId)) { |
| 96 | - if (isRole(STANDBY, nodeId, deviceId)) { | 96 | + return MASTER; |
| 97 | - //was previously standby, or set to standby from master | 97 | + } |
| 98 | - return MastershipRole.STANDBY; | 98 | + if (roleInfo.contains(STANDBY, nodeId)) { |
| 99 | - } else { | 99 | + return STANDBY; |
| 100 | - return MastershipRole.NONE; | ||
| 101 | - } | ||
| 102 | - } else { | ||
| 103 | - if (current.equals(nodeId)) { | ||
| 104 | - //*should* be in unusable, not always | ||
| 105 | - return MastershipRole.MASTER; | ||
| 106 | - } else { | ||
| 107 | - //may be in backups or unusable from earlier retirement | ||
| 108 | - return MastershipRole.STANDBY; | ||
| 109 | - } | ||
| 110 | } | 100 | } |
| 101 | + return NONE; | ||
| 111 | } | 102 | } |
| 112 | 103 | ||
| 113 | @Override | 104 | @Override |
| ... | @@ -124,10 +115,11 @@ implements MastershipStore { | ... | @@ -124,10 +115,11 @@ implements MastershipStore { |
| 124 | roleMap.put(deviceId, rv); | 115 | roleMap.put(deviceId, rv); |
| 125 | return null; | 116 | return null; |
| 126 | case STANDBY: | 117 | case STANDBY: |
| 118 | + case NONE: | ||
| 127 | NodeId current = rv.get(MASTER); | 119 | NodeId current = rv.get(MASTER); |
| 128 | if (current != null) { | 120 | if (current != null) { |
| 129 | //backup and replace current master | 121 | //backup and replace current master |
| 130 | - rv.reassign(nodeId, NONE, STANDBY); | 122 | + rv.reassign(current, NONE, STANDBY); |
| 131 | rv.replace(current, nodeId, MASTER); | 123 | rv.replace(current, nodeId, MASTER); |
| 132 | } else { | 124 | } else { |
| 133 | //no master before so just add. | 125 | //no master before so just add. |
| ... | @@ -137,12 +129,6 @@ implements MastershipStore { | ... | @@ -137,12 +129,6 @@ implements MastershipStore { |
| 137 | roleMap.put(deviceId, rv); | 129 | roleMap.put(deviceId, rv); |
| 138 | updateTerm(deviceId); | 130 | updateTerm(deviceId); |
| 139 | return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo()); | 131 | return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo()); |
| 140 | - case NONE: | ||
| 141 | - rv.add(MASTER, nodeId); | ||
| 142 | - rv.reassign(nodeId, STANDBY, NONE); | ||
| 143 | - roleMap.put(deviceId, rv); | ||
| 144 | - updateTerm(deviceId); | ||
| 145 | - return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo()); | ||
| 146 | default: | 132 | default: |
| 147 | log.warn("unknown Mastership Role {}", role); | 133 | log.warn("unknown Mastership Role {}", role); |
| 148 | return null; | 134 | return null; |
| ... | @@ -193,21 +179,28 @@ implements MastershipStore { | ... | @@ -193,21 +179,28 @@ implements MastershipStore { |
| 193 | switch (role) { | 179 | switch (role) { |
| 194 | case MASTER: | 180 | case MASTER: |
| 195 | rv.reassign(local, STANDBY, NONE); | 181 | rv.reassign(local, STANDBY, NONE); |
| 182 | + terms.putIfAbsent(deviceId, INIT); | ||
| 196 | roleMap.put(deviceId, rv); | 183 | roleMap.put(deviceId, rv); |
| 197 | break; | 184 | break; |
| 198 | case STANDBY: | 185 | case STANDBY: |
| 199 | rv.reassign(local, NONE, STANDBY); | 186 | rv.reassign(local, NONE, STANDBY); |
| 200 | roleMap.put(deviceId, rv); | 187 | roleMap.put(deviceId, rv); |
| 201 | terms.putIfAbsent(deviceId, INIT); | 188 | terms.putIfAbsent(deviceId, INIT); |
| 202 | - | ||
| 203 | break; | 189 | break; |
| 204 | case NONE: | 190 | case NONE: |
| 205 | - //claim mastership | 191 | + //either we're the first standby, or first to device. |
| 206 | - rv.add(MASTER, local); | 192 | + //for latter, claim mastership. |
| 207 | - rv.reassign(local, STANDBY, NONE); | 193 | + if (rv.get(MASTER) == null) { |
| 194 | + rv.add(MASTER, local); | ||
| 195 | + rv.reassign(local, STANDBY, NONE); | ||
| 196 | + updateTerm(deviceId); | ||
| 197 | + role = MastershipRole.MASTER; | ||
| 198 | + } else { | ||
| 199 | + rv.add(STANDBY, local); | ||
| 200 | + rv.reassign(local, NONE, STANDBY); | ||
| 201 | + role = MastershipRole.STANDBY; | ||
| 202 | + } | ||
| 208 | roleMap.put(deviceId, rv); | 203 | roleMap.put(deviceId, rv); |
| 209 | - updateTerm(deviceId); | ||
| 210 | - role = MastershipRole.MASTER; | ||
| 211 | break; | 204 | break; |
| 212 | default: | 205 | default: |
| 213 | log.warn("unknown Mastership Role {}", role); | 206 | log.warn("unknown Mastership Role {}", role); |
| ... | @@ -315,7 +308,10 @@ implements MastershipStore { | ... | @@ -315,7 +308,10 @@ implements MastershipStore { |
| 315 | RoleValue value = roleMap.get(deviceId); | 308 | RoleValue value = roleMap.get(deviceId); |
| 316 | if (value == null) { | 309 | if (value == null) { |
| 317 | value = new RoleValue(); | 310 | value = new RoleValue(); |
| 318 | - roleMap.put(deviceId, value); | 311 | + RoleValue concurrentlyAdded = roleMap.putIfAbsent(deviceId, value); |
| 312 | + if (concurrentlyAdded != null) { | ||
| 313 | + return concurrentlyAdded; | ||
| 314 | + } | ||
| 319 | } | 315 | } |
| 320 | return value; | 316 | return value; |
| 321 | } | 317 | } |
| ... | @@ -329,16 +325,6 @@ implements MastershipStore { | ... | @@ -329,16 +325,6 @@ implements MastershipStore { |
| 329 | return null; | 325 | return null; |
| 330 | } | 326 | } |
| 331 | 327 | ||
| 332 | - //check if node is a certain role given a device | ||
| 333 | - private boolean isRole( | ||
| 334 | - MastershipRole role, NodeId nodeId, DeviceId deviceId) { | ||
| 335 | - RoleValue value = roleMap.get(deviceId); | ||
| 336 | - if (value != null) { | ||
| 337 | - return value.contains(role, nodeId); | ||
| 338 | - } | ||
| 339 | - return false; | ||
| 340 | - } | ||
| 341 | - | ||
| 342 | //adds or updates term information. | 328 | //adds or updates term information. |
| 343 | private void updateTerm(DeviceId deviceId) { | 329 | private void updateTerm(DeviceId deviceId) { |
| 344 | terms.lock(deviceId); | 330 | terms.lock(deviceId); | ... | ... |
| ... | @@ -97,6 +97,7 @@ public class DistributedMastershipStoreTest { | ... | @@ -97,6 +97,7 @@ public class DistributedMastershipStoreTest { |
| 97 | assertEquals("wrong role:", NONE, dms.getRole(N1, DID1)); | 97 | assertEquals("wrong role:", NONE, dms.getRole(N1, DID1)); |
| 98 | testStore.put(DID1, N1, true, false, true); | 98 | testStore.put(DID1, N1, true, false, true); |
| 99 | assertEquals("wrong role:", MASTER, dms.getRole(N1, DID1)); | 99 | assertEquals("wrong role:", MASTER, dms.getRole(N1, DID1)); |
| 100 | + testStore.put(DID1, N2, false, true, false); | ||
| 100 | assertEquals("wrong role:", STANDBY, dms.getRole(N2, DID1)); | 101 | assertEquals("wrong role:", STANDBY, dms.getRole(N2, DID1)); |
| 101 | } | 102 | } |
| 102 | 103 | ||
| ... | @@ -155,6 +156,7 @@ public class DistributedMastershipStoreTest { | ... | @@ -155,6 +156,7 @@ public class DistributedMastershipStoreTest { |
| 155 | 156 | ||
| 156 | //switch over to N2 | 157 | //switch over to N2 |
| 157 | assertEquals("wrong event:", Type.MASTER_CHANGED, dms.setMaster(N2, DID1).type()); | 158 | assertEquals("wrong event:", Type.MASTER_CHANGED, dms.setMaster(N2, DID1).type()); |
| 159 | + System.out.println(dms.getTermFor(DID1).master() + ":" + dms.getTermFor(DID1).termNumber()); | ||
| 158 | assertEquals("wrong term", MastershipTerm.of(N2, 1), dms.getTermFor(DID1)); | 160 | assertEquals("wrong term", MastershipTerm.of(N2, 1), dms.getTermFor(DID1)); |
| 159 | 161 | ||
| 160 | //orphan switch - should be rare case | 162 | //orphan switch - should be rare case |
| ... | @@ -182,14 +184,9 @@ public class DistributedMastershipStoreTest { | ... | @@ -182,14 +184,9 @@ public class DistributedMastershipStoreTest { |
| 182 | assertEquals("wrong event:", Type.MASTER_CHANGED, dms.relinquishRole(N1, DID1).type()); | 184 | assertEquals("wrong event:", Type.MASTER_CHANGED, dms.relinquishRole(N1, DID1).type()); |
| 183 | assertEquals("wrong master", N2, dms.getMaster(DID1)); | 185 | assertEquals("wrong master", N2, dms.getMaster(DID1)); |
| 184 | 186 | ||
| 185 | - //STANDBY - nothing here, either | ||
| 186 | - assertNull("wrong event:", dms.relinquishRole(N1, DID1)); | ||
| 187 | - assertEquals("wrong role for node:", STANDBY, dms.getRole(N1, DID1)); | ||
| 188 | - | ||
| 189 | //all nodes "give up" on device, which goes back to NONE. | 187 | //all nodes "give up" on device, which goes back to NONE. |
| 190 | assertNull("wrong event:", dms.relinquishRole(N2, DID1)); | 188 | assertNull("wrong event:", dms.relinquishRole(N2, DID1)); |
| 191 | assertEquals("wrong role for node:", NONE, dms.getRole(N2, DID1)); | 189 | assertEquals("wrong role for node:", NONE, dms.getRole(N2, DID1)); |
| 192 | - assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID1)); | ||
| 193 | 190 | ||
| 194 | assertEquals("wrong number of retired nodes", 2, | 191 | assertEquals("wrong number of retired nodes", 2, |
| 195 | dms.roleMap.get(DID1).nodesOfRole(NONE).size()); | 192 | dms.roleMap.get(DID1).nodesOfRole(NONE).size()); |
| ... | @@ -201,6 +198,10 @@ public class DistributedMastershipStoreTest { | ... | @@ -201,6 +198,10 @@ public class DistributedMastershipStoreTest { |
| 201 | assertEquals("wrong number of backup nodes", 1, | 198 | assertEquals("wrong number of backup nodes", 1, |
| 202 | dms.roleMap.get(DID1).nodesOfRole(STANDBY).size()); | 199 | dms.roleMap.get(DID1).nodesOfRole(STANDBY).size()); |
| 203 | 200 | ||
| 201 | + //If STANDBY, should drop to NONE | ||
| 202 | + assertNull("wrong event:", dms.relinquishRole(N1, DID1)); | ||
| 203 | + assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID1)); | ||
| 204 | + | ||
| 204 | //NONE - nothing happens | 205 | //NONE - nothing happens |
| 205 | assertNull("wrong event:", dms.relinquishRole(N1, DID2)); | 206 | assertNull("wrong event:", dms.relinquishRole(N1, DID2)); |
| 206 | assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID2)); | 207 | assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID2)); |
| ... | @@ -218,7 +219,7 @@ public class DistributedMastershipStoreTest { | ... | @@ -218,7 +219,7 @@ public class DistributedMastershipStoreTest { |
| 218 | public void notify(MastershipEvent event) { | 219 | public void notify(MastershipEvent event) { |
| 219 | assertEquals("wrong event:", Type.MASTER_CHANGED, event.type()); | 220 | assertEquals("wrong event:", Type.MASTER_CHANGED, event.type()); |
| 220 | assertEquals("wrong subject", DID1, event.subject()); | 221 | assertEquals("wrong subject", DID1, event.subject()); |
| 221 | - assertEquals("wrong subject", N1, event.node()); | 222 | + assertEquals("wrong subject", N1, event.roleInfo().master()); |
| 222 | addLatch.countDown(); | 223 | addLatch.countDown(); |
| 223 | } | 224 | } |
| 224 | }; | 225 | }; | ... | ... |
-
Please register or login to post a comment