blob: 74ca8cd329d5232a4539fe763b247ebb595dc8ba [file] [log] [blame]
Yuta HIGUCHI80912e62014-10-12 00:15:47 -07001package org.onlab.onos.store.mastership.impl;
tomb41d1ac2014-09-24 01:51:24 -07002
Yuta HIGUCHI80912e62014-10-12 00:15:47 -07003import static org.onlab.onos.mastership.MastershipEvent.Type.MASTER_CHANGED;
alshabib339a3d92014-09-26 17:54:32 -07004
5import java.util.Map;
alshabib339a3d92014-09-26 17:54:32 -07006import java.util.Set;
Yuta HIGUCHIc8e19d42014-09-24 17:20:52 -07007
tomb41d1ac2014-09-24 01:51:24 -07008import org.apache.felix.scr.annotations.Activate;
9import org.apache.felix.scr.annotations.Component;
10import org.apache.felix.scr.annotations.Deactivate;
11import org.apache.felix.scr.annotations.Reference;
12import org.apache.felix.scr.annotations.ReferenceCardinality;
13import org.apache.felix.scr.annotations.Service;
14import org.onlab.onos.cluster.ClusterService;
tomb41d1ac2014-09-24 01:51:24 -070015import org.onlab.onos.cluster.NodeId;
Ayaka Koshibeabedb092014-10-20 17:01:31 -070016import org.onlab.onos.cluster.RoleInfo;
Yuta HIGUCHI80912e62014-10-12 00:15:47 -070017import org.onlab.onos.mastership.MastershipEvent;
18import org.onlab.onos.mastership.MastershipStore;
19import org.onlab.onos.mastership.MastershipStoreDelegate;
20import org.onlab.onos.mastership.MastershipTerm;
tomb41d1ac2014-09-24 01:51:24 -070021import org.onlab.onos.net.DeviceId;
22import org.onlab.onos.net.MastershipRole;
Yuta HIGUCHIb5df76d2014-09-27 20:54:00 -070023import org.onlab.onos.store.common.AbstractHazelcastStore;
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070024import org.onlab.onos.store.common.SMap;
Yuta HIGUCHI8d143d22014-10-19 23:15:09 -070025import org.onlab.onos.store.serializers.KryoNamespaces;
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070026import org.onlab.onos.store.serializers.KryoSerializer;
Yuta HIGUCHI8d143d22014-10-19 23:15:09 -070027import org.onlab.util.KryoNamespace;
tomb41d1ac2014-09-24 01:51:24 -070028
alshabib339a3d92014-09-26 17:54:32 -070029import com.google.common.collect.ImmutableSet;
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -070030import com.hazelcast.core.EntryEvent;
31import com.hazelcast.core.EntryListener;
Ayaka Koshibee8e45352014-10-16 00:37:19 -070032import com.hazelcast.core.IAtomicLong;
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -070033import com.hazelcast.core.MapEvent;
tomb41d1ac2014-09-24 01:51:24 -070034
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070035import static org.onlab.onos.net.MastershipRole.*;
36
tomb41d1ac2014-09-24 01:51:24 -070037/**
Ayaka Koshibec4047702014-10-07 14:43:52 -070038 * Distributed implementation of the mastership store. The store is
39 * responsible for the master selection process.
tomb41d1ac2014-09-24 01:51:24 -070040 */
41@Component(immediate = true)
42@Service
tom0755a362014-09-24 11:54:43 -070043public class DistributedMastershipStore
Yuta HIGUCHI2e963892014-09-27 13:00:39 -070044extends AbstractHazelcastStore<MastershipEvent, MastershipStoreDelegate>
alshabib339a3d92014-09-26 17:54:32 -070045implements MastershipStore {
tomb41d1ac2014-09-24 01:51:24 -070046
Ayaka Koshibec4047702014-10-07 14:43:52 -070047 //initial term/TTL value
Ayaka Koshibe8583ff32014-10-02 16:25:30 -070048 private static final Integer INIT = 0;
Ayaka Koshibe8583ff32014-10-02 16:25:30 -070049
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070050 //device to node roles
51 protected SMap<DeviceId, RoleValue> roleMap;
Ayaka Koshibe8583ff32014-10-02 16:25:30 -070052 //devices to terms
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070053 protected SMap<DeviceId, Integer> terms;
Ayaka Koshibee8e45352014-10-16 00:37:19 -070054 //last-known cluster size, used for tie-breaking when partitioning occurs
55 protected IAtomicLong clusterSize;
56
Ayaka Koshibe8583ff32014-10-02 16:25:30 -070057
tomb41d1ac2014-09-24 01:51:24 -070058 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
59 protected ClusterService clusterService;
60
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070061 @SuppressWarnings({ "unchecked", "rawtypes" })
Ayaka Koshibe406d0102014-09-24 16:08:12 -070062 @Override
tomb41d1ac2014-09-24 01:51:24 -070063 @Activate
64 public void activate() {
65 super.activate();
66
Ayaka Koshibee8e45352014-10-16 00:37:19 -070067 this.serializer = new KryoSerializer() {
68 @Override
69 protected void setupKryoPool() {
Yuta HIGUCHI8d143d22014-10-19 23:15:09 -070070 serializerPool = KryoNamespace.newBuilder()
71 .register(KryoNamespaces.API)
Ayaka Koshibee8e45352014-10-16 00:37:19 -070072
73 .register(RoleValue.class, new RoleValueSerializer())
74 .build()
75 .populate(1);
76 }
77 };
78
79 roleMap = new SMap(theInstance.getMap("nodeRoles"), this.serializer);
Ayaka Koshibe67af1f42014-10-20 15:26:37 -070080 roleMap.addEntryListener((new RemoteMasterShipEventHandler()), true);
Ayaka Koshibee8e45352014-10-16 00:37:19 -070081 terms = new SMap(theInstance.getMap("terms"), this.serializer);
82 clusterSize = theInstance.getAtomicLong("clustersize");
Yuta HIGUCHIc8e19d42014-09-24 17:20:52 -070083
tomb41d1ac2014-09-24 01:51:24 -070084 log.info("Started");
85 }
86
87 @Deactivate
88 public void deactivate() {
89 log.info("Stopped");
90 }
91
92 @Override
Ayaka Koshibec4047702014-10-07 14:43:52 -070093 public MastershipRole getRole(NodeId nodeId, DeviceId deviceId) {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070094 NodeId current = getNode(MASTER, deviceId);
Ayaka Koshibec4047702014-10-07 14:43:52 -070095 if (current == null) {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070096 if (isRole(STANDBY, nodeId, deviceId)) {
Ayaka Koshibec4047702014-10-07 14:43:52 -070097 //was previously standby, or set to standby from master
98 return MastershipRole.STANDBY;
99 } else {
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 }
111 }
112
113 @Override
Ayaka Koshibe406d0102014-09-24 16:08:12 -0700114 public MastershipEvent setMaster(NodeId nodeId, DeviceId deviceId) {
tomb41d1ac2014-09-24 01:51:24 -0700115
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700116 MastershipRole role = getRole(nodeId, deviceId);
117 roleMap.lock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700118 try {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700119 RoleValue rv = getRoleValue(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700120 switch (role) {
121 case MASTER:
Ayaka Koshibec4047702014-10-07 14:43:52 -0700122 //reinforce mastership
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700123 rv.reassign(nodeId, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700124 roleMap.put(deviceId, rv);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700125 return null;
126 case STANDBY:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700127 NodeId current = rv.get(MASTER);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700128 if (current != null) {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700129 //backup and replace current master
130 rv.reassign(nodeId, NONE, STANDBY);
131 rv.replace(current, nodeId, MASTER);
132 } else {
133 //no master before so just add.
134 rv.add(MASTER, nodeId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700135 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700136 rv.reassign(nodeId, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700137 roleMap.put(deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700138 updateTerm(deviceId);
Ayaka Koshibefc981cf2014-10-21 12:44:17 -0700139 return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo());
Ayaka Koshibec4047702014-10-07 14:43:52 -0700140 case NONE:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700141 rv.add(MASTER, nodeId);
142 rv.reassign(nodeId, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700143 roleMap.put(deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700144 updateTerm(deviceId);
Ayaka Koshibefc981cf2014-10-21 12:44:17 -0700145 return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo());
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700146 default:
147 log.warn("unknown Mastership Role {}", role);
148 return null;
149 }
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700150 } finally {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700151 roleMap.unlock(deviceId);
tomb41d1ac2014-09-24 01:51:24 -0700152 }
153 }
154
155 @Override
156 public NodeId getMaster(DeviceId deviceId) {
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700157 return getNode(MASTER, deviceId);
tomb41d1ac2014-09-24 01:51:24 -0700158 }
159
Ayaka Koshibe45503ce2014-10-14 11:26:45 -0700160
161 @Override
Ayaka Koshibeabedb092014-10-20 17:01:31 -0700162 public RoleInfo getNodes(DeviceId deviceId) {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700163 roleMap.lock(deviceId);
Ayaka Koshibe45503ce2014-10-14 11:26:45 -0700164 try {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700165 RoleValue rv = getRoleValue(deviceId);
Ayaka Koshibeabedb092014-10-20 17:01:31 -0700166 return rv.roleInfo();
Ayaka Koshibe45503ce2014-10-14 11:26:45 -0700167 } finally {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700168 roleMap.unlock(deviceId);
Ayaka Koshibe45503ce2014-10-14 11:26:45 -0700169 }
170 }
171
tomb41d1ac2014-09-24 01:51:24 -0700172 @Override
173 public Set<DeviceId> getDevices(NodeId nodeId) {
174 ImmutableSet.Builder<DeviceId> builder = ImmutableSet.builder();
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700175
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700176 for (Map.Entry<DeviceId, RoleValue> el : roleMap.entrySet()) {
177 if (nodeId.equals(el.getValue().get(MASTER))) {
178 builder.add(el.getKey());
tomb41d1ac2014-09-24 01:51:24 -0700179 }
180 }
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700181
tomb41d1ac2014-09-24 01:51:24 -0700182 return builder.build();
183 }
184
185 @Override
186 public MastershipRole requestRole(DeviceId deviceId) {
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700187 NodeId local = clusterService.getLocalNode().id();
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700188
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700189 roleMap.lock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700190 try {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700191 RoleValue rv = getRoleValue(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700192 MastershipRole role = getRole(local, deviceId);
193 switch (role) {
194 case MASTER:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700195 rv.reassign(local, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700196 roleMap.put(deviceId, rv);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700197 break;
198 case STANDBY:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700199 rv.reassign(local, NONE, STANDBY);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700200 roleMap.put(deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700201 terms.putIfAbsent(deviceId, INIT);
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700202
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700203 break;
204 case NONE:
Ayaka Koshibec4047702014-10-07 14:43:52 -0700205 //claim mastership
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700206 rv.add(MASTER, local);
207 rv.reassign(local, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700208 roleMap.put(deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700209 updateTerm(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700210 role = MastershipRole.MASTER;
211 break;
212 default:
213 log.warn("unknown Mastership Role {}", role);
214 }
215 return role;
216 } finally {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700217 roleMap.unlock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700218 }
tomb41d1ac2014-09-24 01:51:24 -0700219 }
220
221 @Override
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700222 public MastershipTerm getTermFor(DeviceId deviceId) {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700223 RoleValue rv = getRoleValue(deviceId);
224 if ((rv.get(MASTER) == null) || (terms.get(deviceId) == null)) {
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700225 return null;
226 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700227 return MastershipTerm.of(rv.get(MASTER), terms.get(deviceId));
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700228 }
229
Ayaka Koshibed9f693e2014-09-29 18:04:54 -0700230 @Override
Ayaka Koshibec4047702014-10-07 14:43:52 -0700231 public MastershipEvent setStandby(NodeId nodeId, DeviceId deviceId) {
Ayaka Koshibec4047702014-10-07 14:43:52 -0700232 MastershipEvent event = null;
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700233
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700234 roleMap.lock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700235 try {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700236 RoleValue rv = getRoleValue(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700237 MastershipRole role = getRole(nodeId, deviceId);
238 switch (role) {
239 case MASTER:
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700240 event = reelect(nodeId, deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700241 //fall through to reinforce role
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700242 case STANDBY:
Ayaka Koshibec4047702014-10-07 14:43:52 -0700243 //fall through to reinforce role
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700244 case NONE:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700245 rv.reassign(nodeId, NONE, STANDBY);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700246 roleMap.put(deviceId, rv);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700247 break;
248 default:
249 log.warn("unknown Mastership Role {}", role);
250 }
Ayaka Koshibec4047702014-10-07 14:43:52 -0700251 return event;
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700252 } finally {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700253 roleMap.unlock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700254 }
255 }
256
Ayaka Koshibec4047702014-10-07 14:43:52 -0700257 @Override
258 public MastershipEvent relinquishRole(NodeId nodeId, DeviceId deviceId) {
Ayaka Koshibec4047702014-10-07 14:43:52 -0700259 MastershipEvent event = null;
Ayaka Koshibe25fd23a2014-10-03 15:50:43 -0700260
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700261 roleMap.lock(deviceId);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700262 try {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700263 RoleValue rv = getRoleValue(deviceId);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700264 MastershipRole role = getRole(nodeId, deviceId);
265 switch (role) {
266 case MASTER:
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700267 event = reelect(nodeId, deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700268 //fall through to reinforce relinquishment
Ayaka Koshibec4047702014-10-07 14:43:52 -0700269 case STANDBY:
270 //fall through to reinforce relinquishment
271 case NONE:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700272 rv.reassign(nodeId, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700273 roleMap.put(deviceId, rv);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700274 break;
275 default:
276 log.warn("unknown Mastership Role {}", role);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700277 }
Ayaka Koshibec4047702014-10-07 14:43:52 -0700278 return event;
279 } finally {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700280 roleMap.unlock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700281 }
Ayaka Koshibed9f693e2014-09-29 18:04:54 -0700282 }
283
Ayaka Koshibec4047702014-10-07 14:43:52 -0700284 //helper to fetch a new master candidate for a given device.
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700285 private MastershipEvent reelect(
286 NodeId current, DeviceId deviceId, RoleValue rv) {
Ayaka Koshibec4047702014-10-07 14:43:52 -0700287
288 //if this is an queue it'd be neater.
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700289 NodeId backup = null;
290 for (NodeId n : rv.nodesOfRole(STANDBY)) {
291 if (!current.equals(n)) {
Ayaka Koshibec4047702014-10-07 14:43:52 -0700292 backup = n;
293 break;
294 }
295 }
296
297 if (backup == null) {
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700298 log.info("{} giving up and going to NONE for {}", current, deviceId);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700299 rv.remove(MASTER, current);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700300 roleMap.put(deviceId, rv);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700301 return null;
302 } else {
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700303 log.info("{} trying to pass mastership for {} to {}", current, deviceId, backup);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700304 rv.replace(current, backup, MASTER);
305 rv.reassign(backup, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700306 roleMap.put(deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700307 Integer term = terms.get(deviceId);
308 terms.put(deviceId, ++term);
Ayaka Koshibefc981cf2014-10-21 12:44:17 -0700309 return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo());
Ayaka Koshibec4047702014-10-07 14:43:52 -0700310 }
311 }
312
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700313 //return the RoleValue structure for a device, or create one
314 private RoleValue getRoleValue(DeviceId deviceId) {
315 RoleValue value = roleMap.get(deviceId);
316 if (value == null) {
317 value = new RoleValue();
318 roleMap.put(deviceId, value);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700319 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700320 return value;
Ayaka Koshibec4047702014-10-07 14:43:52 -0700321 }
322
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700323 //get first applicable node out of store-unique structure.
324 private NodeId getNode(MastershipRole role, DeviceId deviceId) {
325 RoleValue value = roleMap.get(deviceId);
326 if (value != null) {
327 return value.get(role);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700328 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700329 return null;
330 }
331
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);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700338 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700339 return false;
Ayaka Koshibec4047702014-10-07 14:43:52 -0700340 }
341
342 //adds or updates term information.
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700343 private void updateTerm(DeviceId deviceId) {
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700344 terms.lock(deviceId);
345 try {
346 Integer term = terms.get(deviceId);
347 if (term == null) {
348 terms.put(deviceId, INIT);
349 } else {
350 terms.put(deviceId, ++term);
351 }
352 } finally {
353 terms.unlock(deviceId);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700354 }
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700355 }
356
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700357 private class RemoteMasterShipEventHandler implements EntryListener<DeviceId, RoleValue> {
alshabib339a3d92014-09-26 17:54:32 -0700358
359 @Override
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700360 public void entryAdded(EntryEvent<DeviceId, RoleValue> event) {
alshabib339a3d92014-09-26 17:54:32 -0700361 }
362
363 @Override
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700364 public void entryRemoved(EntryEvent<DeviceId, RoleValue> event) {
alshabib339a3d92014-09-26 17:54:32 -0700365 }
366
367 @Override
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700368 public void entryUpdated(EntryEvent<DeviceId, RoleValue> event) {
369 NodeId myId = clusterService.getLocalNode().id();
370 NodeId node = event.getValue().get(MASTER);
371 if (myId.equals(node)) {
372 // XXX or do we just let it get sent and caught by ourself?
373 return;
374 }
375 notifyDelegate(new MastershipEvent(
Ayaka Koshibefc981cf2014-10-21 12:44:17 -0700376 MASTER_CHANGED, event.getKey(), event.getValue().roleInfo()));
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700377 }
378
379 @Override
380 public void entryEvicted(EntryEvent<DeviceId, RoleValue> event) {
381 }
382
383 @Override
384 public void mapEvicted(MapEvent event) {
385 }
386
387 @Override
388 public void mapCleared(MapEvent event) {
alshabib339a3d92014-09-26 17:54:32 -0700389 }
390 }
391
tomb41d1ac2014-09-24 01:51:24 -0700392}