blob: 75c040531cb5f2d55d427ec45fe33eceaf3f861f [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
2 * Copyright 2014 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Yuta HIGUCHI80912e62014-10-12 00:15:47 -070016package org.onlab.onos.store.mastership.impl;
tomb41d1ac2014-09-24 01:51:24 -070017
Yuta HIGUCHI80912e62014-10-12 00:15:47 -070018import static org.onlab.onos.mastership.MastershipEvent.Type.MASTER_CHANGED;
alshabib339a3d92014-09-26 17:54:32 -070019
20import java.util.Map;
alshabib339a3d92014-09-26 17:54:32 -070021import java.util.Set;
Yuta HIGUCHIc8e19d42014-09-24 17:20:52 -070022
tomb41d1ac2014-09-24 01:51:24 -070023import org.apache.felix.scr.annotations.Activate;
24import org.apache.felix.scr.annotations.Component;
25import org.apache.felix.scr.annotations.Deactivate;
26import org.apache.felix.scr.annotations.Reference;
27import org.apache.felix.scr.annotations.ReferenceCardinality;
28import org.apache.felix.scr.annotations.Service;
29import org.onlab.onos.cluster.ClusterService;
tomb41d1ac2014-09-24 01:51:24 -070030import org.onlab.onos.cluster.NodeId;
Ayaka Koshibeabedb092014-10-20 17:01:31 -070031import org.onlab.onos.cluster.RoleInfo;
Yuta HIGUCHI80912e62014-10-12 00:15:47 -070032import org.onlab.onos.mastership.MastershipEvent;
33import org.onlab.onos.mastership.MastershipStore;
34import org.onlab.onos.mastership.MastershipStoreDelegate;
35import org.onlab.onos.mastership.MastershipTerm;
tomb41d1ac2014-09-24 01:51:24 -070036import org.onlab.onos.net.DeviceId;
37import org.onlab.onos.net.MastershipRole;
Yuta HIGUCHI41f2ec02014-10-27 09:54:43 -070038import org.onlab.onos.store.hz.AbstractHazelcastStore;
39import org.onlab.onos.store.hz.SMap;
Yuta HIGUCHI8d143d22014-10-19 23:15:09 -070040import org.onlab.onos.store.serializers.KryoNamespaces;
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070041import org.onlab.onos.store.serializers.KryoSerializer;
Yuta HIGUCHI8d143d22014-10-19 23:15:09 -070042import org.onlab.util.KryoNamespace;
tomb41d1ac2014-09-24 01:51:24 -070043
alshabib339a3d92014-09-26 17:54:32 -070044import com.google.common.collect.ImmutableSet;
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -070045import com.hazelcast.core.EntryEvent;
46import com.hazelcast.core.EntryListener;
Ayaka Koshibee8e45352014-10-16 00:37:19 -070047import com.hazelcast.core.IAtomicLong;
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -070048import com.hazelcast.core.MapEvent;
Yuta HIGUCHI41f2ec02014-10-27 09:54:43 -070049
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070050import static org.onlab.onos.net.MastershipRole.*;
51
tomb41d1ac2014-09-24 01:51:24 -070052/**
Ayaka Koshibec4047702014-10-07 14:43:52 -070053 * Distributed implementation of the mastership store. The store is
54 * responsible for the master selection process.
tomb41d1ac2014-09-24 01:51:24 -070055 */
56@Component(immediate = true)
57@Service
tom0755a362014-09-24 11:54:43 -070058public class DistributedMastershipStore
Yuta HIGUCHI2e963892014-09-27 13:00:39 -070059extends AbstractHazelcastStore<MastershipEvent, MastershipStoreDelegate>
alshabib339a3d92014-09-26 17:54:32 -070060implements MastershipStore {
tomb41d1ac2014-09-24 01:51:24 -070061
Ayaka Koshibec4047702014-10-07 14:43:52 -070062 //initial term/TTL value
Ayaka Koshibe8583ff32014-10-02 16:25:30 -070063 private static final Integer INIT = 0;
Ayaka Koshibe8583ff32014-10-02 16:25:30 -070064
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070065 //device to node roles
66 protected SMap<DeviceId, RoleValue> roleMap;
Ayaka Koshibe8583ff32014-10-02 16:25:30 -070067 //devices to terms
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -070068 protected SMap<DeviceId, Integer> terms;
Ayaka Koshibee8e45352014-10-16 00:37:19 -070069 //last-known cluster size, used for tie-breaking when partitioning occurs
70 protected IAtomicLong clusterSize;
71
Ayaka Koshibe8583ff32014-10-02 16:25:30 -070072
tomb41d1ac2014-09-24 01:51:24 -070073 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
74 protected ClusterService clusterService;
75
Ayaka Koshibe406d0102014-09-24 16:08:12 -070076 @Override
tomb41d1ac2014-09-24 01:51:24 -070077 @Activate
78 public void activate() {
79 super.activate();
80
Ayaka Koshibee8e45352014-10-16 00:37:19 -070081 this.serializer = new KryoSerializer() {
82 @Override
83 protected void setupKryoPool() {
Yuta HIGUCHI8d143d22014-10-19 23:15:09 -070084 serializerPool = KryoNamespace.newBuilder()
85 .register(KryoNamespaces.API)
Ayaka Koshibee8e45352014-10-16 00:37:19 -070086
87 .register(RoleValue.class, new RoleValueSerializer())
88 .build()
89 .populate(1);
90 }
91 };
92
Yuta HIGUCHI9def0472014-10-23 15:51:10 -070093 roleMap = new SMap<>(theInstance.<byte[], byte[]>getMap("nodeRoles"), this.serializer);
Ayaka Koshibe67af1f42014-10-20 15:26:37 -070094 roleMap.addEntryListener((new RemoteMasterShipEventHandler()), true);
Yuta HIGUCHI9def0472014-10-23 15:51:10 -070095 terms = new SMap<>(theInstance.<byte[], byte[]>getMap("terms"), this.serializer);
Ayaka Koshibee8e45352014-10-16 00:37:19 -070096 clusterSize = theInstance.getAtomicLong("clustersize");
Yuta HIGUCHIc8e19d42014-09-24 17:20:52 -070097
tomb41d1ac2014-09-24 01:51:24 -070098 log.info("Started");
99 }
100
101 @Deactivate
102 public void deactivate() {
103 log.info("Stopped");
104 }
105
106 @Override
Ayaka Koshibec4047702014-10-07 14:43:52 -0700107 public MastershipRole getRole(NodeId nodeId, DeviceId deviceId) {
Ayaka Koshibea7384a82014-10-22 18:59:06 -0700108 final RoleValue roleInfo = getRoleValue(deviceId);
109 if (roleInfo.contains(MASTER, nodeId)) {
110 return MASTER;
Ayaka Koshibec4047702014-10-07 14:43:52 -0700111 }
Ayaka Koshibea7384a82014-10-22 18:59:06 -0700112 if (roleInfo.contains(STANDBY, nodeId)) {
113 return STANDBY;
114 }
115 return NONE;
Ayaka Koshibec4047702014-10-07 14:43:52 -0700116 }
117
118 @Override
Ayaka Koshibe406d0102014-09-24 16:08:12 -0700119 public MastershipEvent setMaster(NodeId nodeId, DeviceId deviceId) {
tomb41d1ac2014-09-24 01:51:24 -0700120
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700121 MastershipRole role = getRole(nodeId, deviceId);
122 roleMap.lock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700123 try {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700124 RoleValue rv = getRoleValue(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700125 switch (role) {
126 case MASTER:
Ayaka Koshibec4047702014-10-07 14:43:52 -0700127 //reinforce mastership
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700128 rv.reassign(nodeId, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700129 roleMap.put(deviceId, rv);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700130 return null;
131 case STANDBY:
Ayaka Koshibea7384a82014-10-22 18:59:06 -0700132 case NONE:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700133 NodeId current = rv.get(MASTER);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700134 if (current != null) {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700135 //backup and replace current master
Ayaka Koshibea7384a82014-10-22 18:59:06 -0700136 rv.reassign(current, NONE, STANDBY);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700137 rv.replace(current, nodeId, MASTER);
138 } else {
139 //no master before so just add.
140 rv.add(MASTER, nodeId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700141 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700142 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 Koshibea7384a82014-10-22 18:59:06 -0700196 terms.putIfAbsent(deviceId, INIT);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700197 roleMap.put(deviceId, rv);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700198 break;
199 case STANDBY:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700200 rv.reassign(local, NONE, STANDBY);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700201 roleMap.put(deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700202 terms.putIfAbsent(deviceId, INIT);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700203 break;
204 case NONE:
Ayaka Koshibea7384a82014-10-22 18:59:06 -0700205 //either we're the first standby, or first to device.
206 //for latter, claim mastership.
207 if (rv.get(MASTER) == null) {
208 rv.add(MASTER, local);
209 rv.reassign(local, STANDBY, NONE);
210 updateTerm(deviceId);
211 role = MastershipRole.MASTER;
212 } else {
213 rv.add(STANDBY, local);
214 rv.reassign(local, NONE, STANDBY);
215 role = MastershipRole.STANDBY;
216 }
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700217 roleMap.put(deviceId, rv);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700218 break;
219 default:
220 log.warn("unknown Mastership Role {}", role);
221 }
222 return role;
223 } finally {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700224 roleMap.unlock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700225 }
tomb41d1ac2014-09-24 01:51:24 -0700226 }
227
228 @Override
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700229 public MastershipTerm getTermFor(DeviceId deviceId) {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700230 RoleValue rv = getRoleValue(deviceId);
231 if ((rv.get(MASTER) == null) || (terms.get(deviceId) == null)) {
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700232 return null;
233 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700234 return MastershipTerm.of(rv.get(MASTER), terms.get(deviceId));
Ayaka Koshibeb70d34b2014-09-25 15:43:01 -0700235 }
236
Ayaka Koshibed9f693e2014-09-29 18:04:54 -0700237 @Override
Ayaka Koshibec4047702014-10-07 14:43:52 -0700238 public MastershipEvent setStandby(NodeId nodeId, DeviceId deviceId) {
Ayaka Koshibec4047702014-10-07 14:43:52 -0700239 MastershipEvent event = null;
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700240
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700241 roleMap.lock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700242 try {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700243 RoleValue rv = getRoleValue(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700244 MastershipRole role = getRole(nodeId, deviceId);
245 switch (role) {
246 case MASTER:
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700247 event = reelect(nodeId, deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700248 //fall through to reinforce role
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700249 case STANDBY:
Ayaka Koshibec4047702014-10-07 14:43:52 -0700250 //fall through to reinforce role
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700251 case NONE:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700252 rv.reassign(nodeId, NONE, STANDBY);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700253 roleMap.put(deviceId, rv);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700254 break;
255 default:
256 log.warn("unknown Mastership Role {}", role);
257 }
Ayaka Koshibec4047702014-10-07 14:43:52 -0700258 return event;
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700259 } finally {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700260 roleMap.unlock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700261 }
262 }
263
Ayaka Koshibec4047702014-10-07 14:43:52 -0700264 @Override
265 public MastershipEvent relinquishRole(NodeId nodeId, DeviceId deviceId) {
Ayaka Koshibec4047702014-10-07 14:43:52 -0700266 MastershipEvent event = null;
Ayaka Koshibe25fd23a2014-10-03 15:50:43 -0700267
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700268 roleMap.lock(deviceId);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700269 try {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700270 RoleValue rv = getRoleValue(deviceId);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700271 MastershipRole role = getRole(nodeId, deviceId);
272 switch (role) {
273 case MASTER:
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700274 event = reelect(nodeId, deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700275 //fall through to reinforce relinquishment
Ayaka Koshibec4047702014-10-07 14:43:52 -0700276 case STANDBY:
277 //fall through to reinforce relinquishment
278 case NONE:
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700279 rv.reassign(nodeId, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700280 roleMap.put(deviceId, rv);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700281 break;
282 default:
283 log.warn("unknown Mastership Role {}", role);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700284 }
Ayaka Koshibec4047702014-10-07 14:43:52 -0700285 return event;
286 } finally {
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700287 roleMap.unlock(deviceId);
Ayaka Koshibe8583ff32014-10-02 16:25:30 -0700288 }
Ayaka Koshibed9f693e2014-09-29 18:04:54 -0700289 }
290
Ayaka Koshibec4047702014-10-07 14:43:52 -0700291 //helper to fetch a new master candidate for a given device.
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700292 private MastershipEvent reelect(
293 NodeId current, DeviceId deviceId, RoleValue rv) {
Ayaka Koshibec4047702014-10-07 14:43:52 -0700294
295 //if this is an queue it'd be neater.
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700296 NodeId backup = null;
297 for (NodeId n : rv.nodesOfRole(STANDBY)) {
298 if (!current.equals(n)) {
Ayaka Koshibec4047702014-10-07 14:43:52 -0700299 backup = n;
300 break;
301 }
302 }
303
304 if (backup == null) {
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700305 log.info("{} giving up and going to NONE for {}", current, deviceId);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700306 rv.remove(MASTER, current);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700307 roleMap.put(deviceId, rv);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700308 return null;
309 } else {
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700310 log.info("{} trying to pass mastership for {} to {}", current, deviceId, backup);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700311 rv.replace(current, backup, MASTER);
312 rv.reassign(backup, STANDBY, NONE);
Ayaka Koshibee8e45352014-10-16 00:37:19 -0700313 roleMap.put(deviceId, rv);
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700314 Integer term = terms.get(deviceId);
315 terms.put(deviceId, ++term);
Ayaka Koshibefc981cf2014-10-21 12:44:17 -0700316 return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo());
Ayaka Koshibec4047702014-10-07 14:43:52 -0700317 }
318 }
319
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700320 //return the RoleValue structure for a device, or create one
321 private RoleValue getRoleValue(DeviceId deviceId) {
322 RoleValue value = roleMap.get(deviceId);
323 if (value == null) {
324 value = new RoleValue();
Ayaka Koshibea7384a82014-10-22 18:59:06 -0700325 RoleValue concurrentlyAdded = roleMap.putIfAbsent(deviceId, value);
326 if (concurrentlyAdded != null) {
327 return concurrentlyAdded;
328 }
Ayaka Koshibec4047702014-10-07 14:43:52 -0700329 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700330 return value;
Ayaka Koshibec4047702014-10-07 14:43:52 -0700331 }
332
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700333 //get first applicable node out of store-unique structure.
334 private NodeId getNode(MastershipRole role, DeviceId deviceId) {
335 RoleValue value = roleMap.get(deviceId);
336 if (value != null) {
337 return value.get(role);
Ayaka Koshibec4047702014-10-07 14:43:52 -0700338 }
Ayaka Koshibef9b02fc2014-10-15 17:07:05 -0700339 return null;
340 }
341
Ayaka Koshibec4047702014-10-07 14:43:52 -0700342 //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) {
Yuta HIGUCHI3195f552014-10-24 22:07:05 -0700369
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700370 notifyDelegate(new MastershipEvent(
Ayaka Koshibefc981cf2014-10-21 12:44:17 -0700371 MASTER_CHANGED, event.getKey(), event.getValue().roleInfo()));
Ayaka Koshibeb5c63a02014-10-18 18:42:27 -0700372 }
373
374 @Override
375 public void entryEvicted(EntryEvent<DeviceId, RoleValue> event) {
376 }
377
378 @Override
379 public void mapEvicted(MapEvent event) {
380 }
381
382 @Override
383 public void mapCleared(MapEvent event) {
alshabib339a3d92014-09-26 17:54:32 -0700384 }
385 }
386
tomb41d1ac2014-09-24 01:51:24 -0700387}