Ayaka Koshibe

fixes for mastership handoff race conditions

Change-Id: Ifed733df1bdc3b144b6a341a9322838ea2aacd72
...@@ -104,7 +104,6 @@ implements MastershipService, MastershipAdminService { ...@@ -104,7 +104,6 @@ implements MastershipService, MastershipAdminService {
104 MastershipEvent event = null; 104 MastershipEvent event = null;
105 event = store.relinquishRole( 105 event = store.relinquishRole(
106 clusterService.getLocalNode().id(), deviceId); 106 clusterService.getLocalNode().id(), deviceId);
107 -
108 if (event != null) { 107 if (event != null) {
109 post(event); 108 post(event);
110 } 109 }
...@@ -229,7 +228,8 @@ implements MastershipService, MastershipAdminService { ...@@ -229,7 +228,8 @@ implements MastershipService, MastershipAdminService {
229 return true; 228 return true;
230 } 229 }
231 //else { 230 //else {
232 - //FIXME: break tie for equal-sized clusters, can we use hz's functions? 231 + //FIXME: break tie for equal-sized clusters,
232 + // maybe by number of connected switches
233 // } 233 // }
234 return false; 234 return false;
235 } 235 }
......
...@@ -161,6 +161,9 @@ public class DeviceManager ...@@ -161,6 +161,9 @@ public class DeviceManager
161 @Override 161 @Override
162 public void removeDevice(DeviceId deviceId) { 162 public void removeDevice(DeviceId deviceId) {
163 checkNotNull(deviceId, DEVICE_ID_NULL); 163 checkNotNull(deviceId, DEVICE_ID_NULL);
164 + // XXX is this intended to apply to the full global topology?
165 + // if so, we probably don't want the fact that we aren't
166 + // MASTER to get in the way, as it would do now.
164 DeviceEvent event = store.removeDevice(deviceId); 167 DeviceEvent event = store.removeDevice(deviceId);
165 if (event != null) { 168 if (event != null) {
166 log.info("Device {} administratively removed", deviceId); 169 log.info("Device {} administratively removed", deviceId);
...@@ -203,19 +206,21 @@ public class DeviceManager ...@@ -203,19 +206,21 @@ public class DeviceManager
203 log.info("Device {} connected", deviceId); 206 log.info("Device {} connected", deviceId);
204 // check my Role 207 // check my Role
205 MastershipRole role = mastershipService.requestRoleFor(deviceId); 208 MastershipRole role = mastershipService.requestRoleFor(deviceId);
206 - 209 + log.info("## - our role for {} is {} [master is {}]", deviceId, role,
210 + mastershipService.getMasterFor(deviceId));
207 if (role != MastershipRole.MASTER) { 211 if (role != MastershipRole.MASTER) {
208 // TODO: Do we need to explicitly tell the Provider that 212 // TODO: Do we need to explicitly tell the Provider that
209 // this instance is no longer the MASTER? probably not 213 // this instance is no longer the MASTER? probably not
210 return; 214 return;
211 } 215 }
212 -
213 MastershipTerm term = mastershipService.requestTermService() 216 MastershipTerm term = mastershipService.requestTermService()
214 .getMastershipTerm(deviceId); 217 .getMastershipTerm(deviceId);
218 +
215 if (!term.master().equals(clusterService.getLocalNode().id())) { 219 if (!term.master().equals(clusterService.getLocalNode().id())) {
216 // lost mastership after requestRole told this instance was MASTER. 220 // lost mastership after requestRole told this instance was MASTER.
217 return; 221 return;
218 } 222 }
223 +
219 // tell clock provider if this instance is the master 224 // tell clock provider if this instance is the master
220 deviceClockProviderService.setMastershipTerm(deviceId, term); 225 deviceClockProviderService.setMastershipTerm(deviceId, term);
221 226
...@@ -256,13 +261,25 @@ public class DeviceManager ...@@ -256,13 +261,25 @@ public class DeviceManager
256 // but if I was the last STANDBY connection, etc. and no one else 261 // but if I was the last STANDBY connection, etc. and no one else
257 // was there to mark the device offline, this instance may need to 262 // was there to mark the device offline, this instance may need to
258 // temporarily request for Master Role and mark offline. 263 // temporarily request for Master Role and mark offline.
264 + log.info("## for {} role is {}", deviceId, mastershipService.getLocalRole(deviceId));
259 if (!mastershipService.getLocalRole(deviceId).equals(MastershipRole.MASTER)) { 265 if (!mastershipService.getLocalRole(deviceId).equals(MastershipRole.MASTER)) {
260 log.debug("Device {} disconnected, but I am not the master", deviceId); 266 log.debug("Device {} disconnected, but I am not the master", deviceId);
261 //let go of ability to be backup 267 //let go of ability to be backup
262 mastershipService.relinquishMastership(deviceId); 268 mastershipService.relinquishMastership(deviceId);
263 return; 269 return;
264 } 270 }
265 - DeviceEvent event = store.markOffline(deviceId); 271 +
272 + DeviceEvent event = null;
273 + try {
274 + event = store.markOffline(deviceId);
275 + } catch (IllegalStateException e) {
276 + //there are times when this node will correctly have mastership, BUT
277 + //that isn't reflected in the ClockManager before the device disconnects.
278 + //we want to let go of the device anyways, so make sure this happens.
279 + MastershipTerm term = termService.getMastershipTerm(deviceId);
280 + deviceClockProviderService.setMastershipTerm(deviceId, term);
281 + event = store.markOffline(deviceId);
282 + } finally {
266 //relinquish master role and ability to be backup. 283 //relinquish master role and ability to be backup.
267 mastershipService.relinquishMastership(deviceId); 284 mastershipService.relinquishMastership(deviceId);
268 285
...@@ -271,6 +288,7 @@ public class DeviceManager ...@@ -271,6 +288,7 @@ public class DeviceManager
271 post(event); 288 post(event);
272 } 289 }
273 } 290 }
291 + }
274 292
275 @Override 293 @Override
276 public void updatePorts(DeviceId deviceId, 294 public void updatePorts(DeviceId deviceId,
...@@ -279,7 +297,15 @@ public class DeviceManager ...@@ -279,7 +297,15 @@ public class DeviceManager
279 checkNotNull(portDescriptions, 297 checkNotNull(portDescriptions,
280 "Port descriptions list cannot be null"); 298 "Port descriptions list cannot be null");
281 checkValidity(); 299 checkValidity();
300 + //XXX what's this doing here?
282 this.provider().id(); 301 this.provider().id();
302 +
303 + if (!mastershipService.getLocalRole(deviceId).equals(MastershipRole.MASTER)) {
304 + // TODO If we become master, then we'll trigger something to update this
305 + // info to fix any inconsistencies that may result during the handoff.
306 + return;
307 + }
308 +
283 List<DeviceEvent> events = store.updatePorts(this.provider().id(), 309 List<DeviceEvent> events = store.updatePorts(this.provider().id(),
284 deviceId, portDescriptions); 310 deviceId, portDescriptions);
285 for (DeviceEvent event : events) { 311 for (DeviceEvent event : events) {
...@@ -293,6 +319,12 @@ public class DeviceManager ...@@ -293,6 +319,12 @@ public class DeviceManager
293 checkNotNull(deviceId, DEVICE_ID_NULL); 319 checkNotNull(deviceId, DEVICE_ID_NULL);
294 checkNotNull(portDescription, PORT_DESCRIPTION_NULL); 320 checkNotNull(portDescription, PORT_DESCRIPTION_NULL);
295 checkValidity(); 321 checkValidity();
322 +
323 + if (!mastershipService.getLocalRole(deviceId).equals(MastershipRole.MASTER)) {
324 + // TODO If we become master, then we'll trigger something to update this
325 + // info to fix any inconsistencies that may result during the handoff.
326 + return;
327 + }
296 DeviceEvent event = store.updatePortStatus(this.provider().id(), 328 DeviceEvent event = store.updatePortStatus(this.provider().id(),
297 deviceId, portDescription); 329 deviceId, portDescription);
298 if (event != null) { 330 if (event != null) {
...@@ -328,27 +360,37 @@ public class DeviceManager ...@@ -328,27 +360,37 @@ public class DeviceManager
328 final DeviceId did = event.subject(); 360 final DeviceId did = event.subject();
329 final NodeId myNodeId = clusterService.getLocalNode().id(); 361 final NodeId myNodeId = clusterService.getLocalNode().id();
330 362
363 + log.info("## got Mastershipevent for dev {}", did);
331 if (myNodeId.equals(event.master())) { 364 if (myNodeId.equals(event.master())) {
332 MastershipTerm term = termService.getMastershipTerm(did); 365 MastershipTerm term = termService.getMastershipTerm(did);
333 366
334 - if (term.master().equals(myNodeId)) { 367 + if (!myNodeId.equals(term.master())) {
368 + // something went wrong in consistency, let go
369 + mastershipService.relinquishMastership(did);
370 + applyRole(did, MastershipRole.STANDBY);
371 + return;
372 + }
373 +
374 + log.info("## setting term for CPS as new master for {}", did);
335 // only set the new term if I am the master 375 // only set the new term if I am the master
336 deviceClockProviderService.setMastershipTerm(did, term); 376 deviceClockProviderService.setMastershipTerm(did, term);
337 - }
338 377
339 // FIXME: we should check that the device is connected on our end. 378 // FIXME: we should check that the device is connected on our end.
340 // currently, this is not straight forward as the actual switch 379 // currently, this is not straight forward as the actual switch
341 - // implementation is hidden from the registry. 380 + // implementation is hidden from the registry. Maybe we can ask the
342 - if (!isAvailable(did)) { 381 + // provider.
343 - //flag the device as online. Is there a better way to do this? 382 + // if the device is null here, we are the first master to claim the
383 + // device. No worries, the DeviceManager will create one soon.
344 Device device = getDevice(did); 384 Device device = getDevice(did);
385 + if ((device != null) && !isAvailable(did)) {
386 + //flag the device as online. Is there a better way to do this?
345 store.createOrUpdateDevice(device.providerId(), did, 387 store.createOrUpdateDevice(device.providerId(), did,
346 new DefaultDeviceDescription( 388 new DefaultDeviceDescription(
347 did.uri(), device.type(), device.manufacturer(), 389 did.uri(), device.type(), device.manufacturer(),
348 device.hwVersion(), device.swVersion(), 390 device.hwVersion(), device.swVersion(),
349 device.serialNumber())); 391 device.serialNumber()));
350 } 392 }
351 - 393 + //TODO re-collect device information to fix potential staleness
352 applyRole(did, MastershipRole.MASTER); 394 applyRole(did, MastershipRole.MASTER);
353 } else { 395 } else {
354 applyRole(did, MastershipRole.STANDBY); 396 applyRole(did, MastershipRole.STANDBY);
......
...@@ -16,6 +16,7 @@ import org.onlab.onos.event.EventDeliveryService; ...@@ -16,6 +16,7 @@ import org.onlab.onos.event.EventDeliveryService;
16 import org.onlab.onos.net.ConnectPoint; 16 import org.onlab.onos.net.ConnectPoint;
17 import org.onlab.onos.net.DeviceId; 17 import org.onlab.onos.net.DeviceId;
18 import org.onlab.onos.net.Link; 18 import org.onlab.onos.net.Link;
19 +import org.onlab.onos.net.MastershipRole;
19 import org.onlab.onos.net.device.DeviceEvent; 20 import org.onlab.onos.net.device.DeviceEvent;
20 import org.onlab.onos.net.device.DeviceListener; 21 import org.onlab.onos.net.device.DeviceListener;
21 import org.onlab.onos.net.device.DeviceService; 22 import org.onlab.onos.net.device.DeviceService;
...@@ -139,11 +140,17 @@ public class LinkManager ...@@ -139,11 +140,17 @@ public class LinkManager
139 140
140 @Override 141 @Override
141 public void removeLinks(ConnectPoint connectPoint) { 142 public void removeLinks(ConnectPoint connectPoint) {
143 + if (deviceService.getRole(connectPoint.deviceId()) != MastershipRole.MASTER) {
144 + return;
145 + }
142 removeLinks(getLinks(connectPoint)); 146 removeLinks(getLinks(connectPoint));
143 } 147 }
144 148
145 @Override 149 @Override
146 public void removeLinks(DeviceId deviceId) { 150 public void removeLinks(DeviceId deviceId) {
151 + if (deviceService.getRole(deviceId) != MastershipRole.MASTER) {
152 + return;
153 + }
147 removeLinks(getDeviceLinks(deviceId)); 154 removeLinks(getDeviceLinks(deviceId));
148 } 155 }
149 156
...@@ -189,6 +196,15 @@ public class LinkManager ...@@ -189,6 +196,15 @@ public class LinkManager
189 public void linkDetected(LinkDescription linkDescription) { 196 public void linkDetected(LinkDescription linkDescription) {
190 checkNotNull(linkDescription, LINK_DESC_NULL); 197 checkNotNull(linkDescription, LINK_DESC_NULL);
191 checkValidity(); 198 checkValidity();
199 +
200 + ConnectPoint src = linkDescription.src();
201 + ConnectPoint dst = linkDescription.dst();
202 + // if we aren't master for the device associated with the ConnectPoint
203 + // we probably shouldn't be doing this.
204 + if ((deviceService.getRole(src.deviceId()) != MastershipRole.MASTER) ||
205 + (deviceService.getRole(dst.deviceId()) != MastershipRole.MASTER)) {
206 + return;
207 + }
192 LinkEvent event = store.createOrUpdateLink(provider().id(), 208 LinkEvent event = store.createOrUpdateLink(provider().id(),
193 linkDescription); 209 linkDescription);
194 if (event != null) { 210 if (event != null) {
...@@ -201,6 +217,15 @@ public class LinkManager ...@@ -201,6 +217,15 @@ public class LinkManager
201 public void linkVanished(LinkDescription linkDescription) { 217 public void linkVanished(LinkDescription linkDescription) {
202 checkNotNull(linkDescription, LINK_DESC_NULL); 218 checkNotNull(linkDescription, LINK_DESC_NULL);
203 checkValidity(); 219 checkValidity();
220 +
221 + ConnectPoint src = linkDescription.src();
222 + ConnectPoint dst = linkDescription.dst();
223 + // if we aren't master for the device associated with the ConnectPoint
224 + // we probably shouldn't be doing this.
225 + if ((deviceService.getRole(src.deviceId()) != MastershipRole.MASTER) ||
226 + (deviceService.getRole(dst.deviceId()) != MastershipRole.MASTER)) {
227 + return;
228 + }
204 LinkEvent event = store.removeLink(linkDescription.src(), 229 LinkEvent event = store.removeLink(linkDescription.src(),
205 linkDescription.dst()); 230 linkDescription.dst());
206 if (event != null) { 231 if (event != null) {
...@@ -213,6 +238,11 @@ public class LinkManager ...@@ -213,6 +238,11 @@ public class LinkManager
213 public void linksVanished(ConnectPoint connectPoint) { 238 public void linksVanished(ConnectPoint connectPoint) {
214 checkNotNull(connectPoint, "Connect point cannot be null"); 239 checkNotNull(connectPoint, "Connect point cannot be null");
215 checkValidity(); 240 checkValidity();
241 + // if we aren't master for the device associated with the ConnectPoint
242 + // we probably shouldn't be doing this.
243 + if (deviceService.getRole(connectPoint.deviceId()) != MastershipRole.MASTER) {
244 + return;
245 + }
216 log.info("Links for connection point {} vanished", connectPoint); 246 log.info("Links for connection point {} vanished", connectPoint);
217 removeLinks(getLinks(connectPoint)); 247 removeLinks(getLinks(connectPoint));
218 } 248 }
...@@ -221,6 +251,11 @@ public class LinkManager ...@@ -221,6 +251,11 @@ public class LinkManager
221 public void linksVanished(DeviceId deviceId) { 251 public void linksVanished(DeviceId deviceId) {
222 checkNotNull(deviceId, DEVICE_ID_NULL); 252 checkNotNull(deviceId, DEVICE_ID_NULL);
223 checkValidity(); 253 checkValidity();
254 + // if we aren't master for the device associated with the ConnectPoint
255 + // we probably shouldn't be doing this.
256 + if (deviceService.getRole(deviceId) != MastershipRole.MASTER) {
257 + return;
258 + }
224 log.info("Links for device {} vanished", deviceId); 259 log.info("Links for device {} vanished", deviceId);
225 removeLinks(getDeviceLinks(deviceId)); 260 removeLinks(getDeviceLinks(deviceId));
226 } 261 }
......
...@@ -59,6 +59,7 @@ public class LinkManagerTest { ...@@ -59,6 +59,7 @@ public class LinkManagerTest {
59 protected LinkProviderService providerService; 59 protected LinkProviderService providerService;
60 protected TestProvider provider; 60 protected TestProvider provider;
61 protected TestListener listener = new TestListener(); 61 protected TestListener listener = new TestListener();
62 + protected DeviceManager devmgr = new TestDeviceManager();
62 63
63 @Before 64 @Before
64 public void setUp() { 65 public void setUp() {
...@@ -68,7 +69,7 @@ public class LinkManagerTest { ...@@ -68,7 +69,7 @@ public class LinkManagerTest {
68 registry = mgr; 69 registry = mgr;
69 mgr.store = new SimpleLinkStore(); 70 mgr.store = new SimpleLinkStore();
70 mgr.eventDispatcher = new TestEventDispatcher(); 71 mgr.eventDispatcher = new TestEventDispatcher();
71 - mgr.deviceService = new DeviceManager(); 72 + mgr.deviceService = devmgr;
72 mgr.activate(); 73 mgr.activate();
73 74
74 service.addListener(listener); 75 service.addListener(listener);
...@@ -259,4 +260,11 @@ public class LinkManagerTest { ...@@ -259,4 +260,11 @@ public class LinkManagerTest {
259 } 260 }
260 } 261 }
261 262
263 + private static class TestDeviceManager extends DeviceManager {
264 + @Override
265 + public MastershipRole getRole(DeviceId deviceId) {
266 + return MastershipRole.MASTER;
267 + }
268 + }
269 +
262 } 270 }
......
...@@ -44,6 +44,8 @@ public class DeviceClockManager implements DeviceClockService, DeviceClockProvid ...@@ -44,6 +44,8 @@ public class DeviceClockManager implements DeviceClockService, DeviceClockProvid
44 @Override 44 @Override
45 public Timestamp getTimestamp(DeviceId deviceId) { 45 public Timestamp getTimestamp(DeviceId deviceId) {
46 MastershipTerm term = deviceMastershipTerms.get(deviceId); 46 MastershipTerm term = deviceMastershipTerms.get(deviceId);
47 + log.info("term info for {} is: {}", deviceId, term);
48 +
47 if (term == null) { 49 if (term == null) {
48 throw new IllegalStateException("Requesting timestamp for a deviceId without mastership"); 50 throw new IllegalStateException("Requesting timestamp for a deviceId without mastership");
49 } 51 }
...@@ -52,6 +54,7 @@ public class DeviceClockManager implements DeviceClockService, DeviceClockProvid ...@@ -52,6 +54,7 @@ public class DeviceClockManager implements DeviceClockService, DeviceClockProvid
52 54
53 @Override 55 @Override
54 public void setMastershipTerm(DeviceId deviceId, MastershipTerm term) { 56 public void setMastershipTerm(DeviceId deviceId, MastershipTerm term) {
57 + log.info("adding term info {} {}", deviceId, term.master());
55 deviceMastershipTerms.put(deviceId, term); 58 deviceMastershipTerms.put(deviceId, term);
56 } 59 }
57 } 60 }
......
...@@ -390,6 +390,7 @@ public class GossipDeviceStore ...@@ -390,6 +390,7 @@ public class GossipDeviceStore
390 List<PortDescription> portDescriptions) { 390 List<PortDescription> portDescriptions) {
391 391
392 final Timestamp newTimestamp = deviceClockService.getTimestamp(deviceId); 392 final Timestamp newTimestamp = deviceClockService.getTimestamp(deviceId);
393 + log.info("timestamp for {} {}", deviceId, newTimestamp);
393 394
394 final Timestamped<List<PortDescription>> timestampedInput 395 final Timestamped<List<PortDescription>> timestampedInput
395 = new Timestamped<>(portDescriptions, newTimestamp); 396 = new Timestamped<>(portDescriptions, newTimestamp);
......
...@@ -360,7 +360,14 @@ public class GossipLinkStore ...@@ -360,7 +360,14 @@ public class GossipLinkStore
360 final LinkKey key = linkKey(src, dst); 360 final LinkKey key = linkKey(src, dst);
361 361
362 DeviceId dstDeviceId = dst.deviceId(); 362 DeviceId dstDeviceId = dst.deviceId();
363 - Timestamp timestamp = deviceClockService.getTimestamp(dstDeviceId); 363 + Timestamp timestamp = null;
364 + try {
365 + timestamp = deviceClockService.getTimestamp(dstDeviceId);
366 + } catch (IllegalStateException e) {
367 + //there are times when this is called before mastership
368 + // handoff correctly completes.
369 + return null;
370 + }
364 371
365 LinkEvent event = removeLinkInternal(key, timestamp); 372 LinkEvent event = removeLinkInternal(key, timestamp);
366 373
......
...@@ -29,7 +29,10 @@ import org.onlab.onos.store.serializers.KryoSerializer; ...@@ -29,7 +29,10 @@ import org.onlab.onos.store.serializers.KryoSerializer;
29 import org.onlab.util.KryoPool; 29 import org.onlab.util.KryoPool;
30 30
31 import com.google.common.collect.ImmutableSet; 31 import com.google.common.collect.ImmutableSet;
32 +import com.hazelcast.core.EntryEvent;
33 +import com.hazelcast.core.EntryListener;
32 import com.hazelcast.core.IAtomicLong; 34 import com.hazelcast.core.IAtomicLong;
35 +import com.hazelcast.core.MapEvent;
33 36
34 import static org.onlab.onos.net.MastershipRole.*; 37 import static org.onlab.onos.net.MastershipRole.*;
35 38
...@@ -78,7 +81,7 @@ implements MastershipStore { ...@@ -78,7 +81,7 @@ implements MastershipStore {
78 roleMap = new SMap(theInstance.getMap("nodeRoles"), this.serializer); 81 roleMap = new SMap(theInstance.getMap("nodeRoles"), this.serializer);
79 terms = new SMap(theInstance.getMap("terms"), this.serializer); 82 terms = new SMap(theInstance.getMap("terms"), this.serializer);
80 clusterSize = theInstance.getAtomicLong("clustersize"); 83 clusterSize = theInstance.getAtomicLong("clustersize");
81 - // roleMap.addEntryListener(new RemoteMasterShipEventHandler(), true); 84 + roleMap.addEntryListener((new RemoteMasterShipEventHandler()), true);
82 85
83 log.info("Started"); 86 log.info("Started");
84 } 87 }
...@@ -207,6 +210,7 @@ implements MastershipStore { ...@@ -207,6 +210,7 @@ implements MastershipStore {
207 rv.reassign(local, NONE, STANDBY); 210 rv.reassign(local, NONE, STANDBY);
208 roleMap.put(deviceId, rv); 211 roleMap.put(deviceId, rv);
209 terms.putIfAbsent(deviceId, INIT); 212 terms.putIfAbsent(deviceId, INIT);
213 +
210 break; 214 break;
211 case NONE: 215 case NONE:
212 //claim mastership 216 //claim mastership
...@@ -289,7 +293,8 @@ implements MastershipStore { ...@@ -289,7 +293,8 @@ implements MastershipStore {
289 } 293 }
290 294
291 //helper to fetch a new master candidate for a given device. 295 //helper to fetch a new master candidate for a given device.
292 - private MastershipEvent reelect(NodeId current, DeviceId deviceId, RoleValue rv) { 296 + private MastershipEvent reelect(
297 + NodeId current, DeviceId deviceId, RoleValue rv) {
293 298
294 //if this is an queue it'd be neater. 299 //if this is an queue it'd be neater.
295 NodeId backup = null; 300 NodeId backup = null;
...@@ -301,17 +306,18 @@ implements MastershipStore { ...@@ -301,17 +306,18 @@ implements MastershipStore {
301 } 306 }
302 307
303 if (backup == null) { 308 if (backup == null) {
309 + log.info("{} giving up and going to NONE for {}", current, deviceId);
304 rv.remove(MASTER, current); 310 rv.remove(MASTER, current);
305 roleMap.put(deviceId, rv); 311 roleMap.put(deviceId, rv);
306 return null; 312 return null;
307 } else { 313 } else {
314 + log.info("{} trying to pass mastership for {} to {}", current, deviceId, backup);
308 rv.replace(current, backup, MASTER); 315 rv.replace(current, backup, MASTER);
309 rv.reassign(backup, STANDBY, NONE); 316 rv.reassign(backup, STANDBY, NONE);
310 roleMap.put(deviceId, rv); 317 roleMap.put(deviceId, rv);
311 Integer term = terms.get(deviceId); 318 Integer term = terms.get(deviceId);
312 terms.put(deviceId, ++term); 319 terms.put(deviceId, ++term);
313 - return new MastershipEvent( 320 + return new MastershipEvent(MASTER_CHANGED, deviceId, backup);
314 - MASTER_CHANGED, deviceId, backup);
315 } 321 }
316 } 322 }
317 323
...@@ -346,30 +352,51 @@ implements MastershipStore { ...@@ -346,30 +352,51 @@ implements MastershipStore {
346 352
347 //adds or updates term information. 353 //adds or updates term information.
348 private void updateTerm(DeviceId deviceId) { 354 private void updateTerm(DeviceId deviceId) {
355 + terms.lock(deviceId);
356 + try {
349 Integer term = terms.get(deviceId); 357 Integer term = terms.get(deviceId);
350 if (term == null) { 358 if (term == null) {
351 terms.put(deviceId, INIT); 359 terms.put(deviceId, INIT);
352 } else { 360 } else {
353 terms.put(deviceId, ++term); 361 terms.put(deviceId, ++term);
354 } 362 }
363 + } finally {
364 + terms.unlock(deviceId);
365 + }
366 + }
367 +
368 + private class RemoteMasterShipEventHandler implements EntryListener<DeviceId, RoleValue> {
369 +
370 + @Override
371 + public void entryAdded(EntryEvent<DeviceId, RoleValue> event) {
372 + }
373 +
374 + @Override
375 + public void entryRemoved(EntryEvent<DeviceId, RoleValue> event) {
355 } 376 }
356 377
357 - private class RemoteMasterShipEventHandler extends RemoteEventHandler<DeviceId, NodeId> { 378 + @Override
379 + public void entryUpdated(EntryEvent<DeviceId, RoleValue> event) {
380 + NodeId myId = clusterService.getLocalNode().id();
381 + NodeId node = event.getValue().get(MASTER);
382 + if (myId.equals(node)) {
383 + // XXX or do we just let it get sent and caught by ourself?
384 + return;
385 + }
386 + notifyDelegate(new MastershipEvent(
387 + MASTER_CHANGED, event.getKey(), event.getValue().get(MASTER)));
388 + }
358 389
359 @Override 390 @Override
360 - protected void onAdd(DeviceId deviceId, NodeId nodeId) { 391 + public void entryEvicted(EntryEvent<DeviceId, RoleValue> event) {
361 - notifyDelegate(new MastershipEvent(MASTER_CHANGED, deviceId, nodeId));
362 } 392 }
363 393
364 @Override 394 @Override
365 - protected void onRemove(DeviceId deviceId, NodeId nodeId) { 395 + public void mapEvicted(MapEvent event) {
366 - //notifyDelegate(new MastershipEvent(MASTER_CHANGED, deviceId, nodeId));
367 } 396 }
368 397
369 @Override 398 @Override
370 - protected void onUpdate(DeviceId deviceId, NodeId oldNodeId, NodeId nodeId) { 399 + public void mapCleared(MapEvent event) {
371 - //only addition indicates a change in mastership
372 - //notifyDelegate(new MastershipEvent(MASTER_CHANGED, deviceId, nodeId));
373 } 400 }
374 } 401 }
375 402
......
...@@ -94,7 +94,6 @@ public final class KryoPoolUtil { ...@@ -94,7 +94,6 @@ public final class KryoPoolUtil {
94 .register(ConnectPoint.class, new ConnectPointSerializer()) 94 .register(ConnectPoint.class, new ConnectPointSerializer())
95 .register(DefaultLink.class, new DefaultLinkSerializer()) 95 .register(DefaultLink.class, new DefaultLinkSerializer())
96 .register(MastershipTerm.class, new MastershipTermSerializer()) 96 .register(MastershipTerm.class, new MastershipTermSerializer())
97 - .register(MastershipRole.class, new MastershipRoleSerializer())
98 .register(HostLocation.class, new HostLocationSerializer()) 97 .register(HostLocation.class, new HostLocationSerializer())
99 98
100 .build(); 99 .build();
......