Committed by
Brian O'Connor
Using ClusterCommunicationService instead of ITopic for notifying cluster member…
…s of leadership events. Change-Id: I164f30da436f3e4f65c4e938c25bb2aa2faa16c3
Showing
1 changed file
with
60 additions
and
42 deletions
| ... | @@ -18,9 +18,6 @@ package org.onosproject.store.cluster.impl; | ... | @@ -18,9 +18,6 @@ package org.onosproject.store.cluster.impl; |
| 18 | import com.google.common.collect.Maps; | 18 | import com.google.common.collect.Maps; |
| 19 | import com.hazelcast.config.TopicConfig; | 19 | import com.hazelcast.config.TopicConfig; |
| 20 | import com.hazelcast.core.IAtomicLong; | 20 | import com.hazelcast.core.IAtomicLong; |
| 21 | -import com.hazelcast.core.ITopic; | ||
| 22 | -import com.hazelcast.core.Message; | ||
| 23 | -import com.hazelcast.core.MessageListener; | ||
| 24 | import org.apache.felix.scr.annotations.Activate; | 21 | import org.apache.felix.scr.annotations.Activate; |
| 25 | import org.apache.felix.scr.annotations.Component; | 22 | import org.apache.felix.scr.annotations.Component; |
| 26 | import org.apache.felix.scr.annotations.Deactivate; | 23 | import org.apache.felix.scr.annotations.Deactivate; |
| ... | @@ -36,6 +33,10 @@ import org.onosproject.cluster.LeadershipService; | ... | @@ -36,6 +33,10 @@ import org.onosproject.cluster.LeadershipService; |
| 36 | import org.onosproject.cluster.NodeId; | 33 | import org.onosproject.cluster.NodeId; |
| 37 | import org.onosproject.event.AbstractListenerRegistry; | 34 | import org.onosproject.event.AbstractListenerRegistry; |
| 38 | import org.onosproject.event.EventDeliveryService; | 35 | import org.onosproject.event.EventDeliveryService; |
| 36 | +import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | ||
| 37 | +import org.onosproject.store.cluster.messaging.ClusterMessage; | ||
| 38 | +import org.onosproject.store.cluster.messaging.ClusterMessageHandler; | ||
| 39 | +import org.onosproject.store.cluster.messaging.MessageSubject; | ||
| 39 | import org.onosproject.store.hz.StoreService; | 40 | import org.onosproject.store.hz.StoreService; |
| 40 | import org.onosproject.store.serializers.KryoNamespaces; | 41 | import org.onosproject.store.serializers.KryoNamespaces; |
| 41 | import org.onosproject.store.serializers.KryoSerializer; | 42 | import org.onosproject.store.serializers.KryoSerializer; |
| ... | @@ -71,8 +72,7 @@ import static org.onlab.util.Tools.namedThreads; | ... | @@ -71,8 +72,7 @@ import static org.onlab.util.Tools.namedThreads; |
| 71 | */ | 72 | */ |
| 72 | @Component(immediate = true) | 73 | @Component(immediate = true) |
| 73 | @Service | 74 | @Service |
| 74 | -public class HazelcastLeadershipService implements LeadershipService, | 75 | +public class HazelcastLeadershipService implements LeadershipService { |
| 75 | - MessageListener<byte[]> { | ||
| 76 | private static final Logger log = | 76 | private static final Logger log = |
| 77 | LoggerFactory.getLogger(HazelcastLeadershipService.class); | 77 | LoggerFactory.getLogger(HazelcastLeadershipService.class); |
| 78 | 78 | ||
| ... | @@ -94,6 +94,9 @@ public class HazelcastLeadershipService implements LeadershipService, | ... | @@ -94,6 +94,9 @@ public class HazelcastLeadershipService implements LeadershipService, |
| 94 | private static final long NO_TERM = 0; | 94 | private static final long NO_TERM = 0; |
| 95 | 95 | ||
| 96 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 96 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 97 | + protected ClusterCommunicationService clusterCommunicator; | ||
| 98 | + | ||
| 99 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 97 | protected ClusterService clusterService; | 100 | protected ClusterService clusterService; |
| 98 | 101 | ||
| 99 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 102 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| ... | @@ -107,8 +110,8 @@ public class HazelcastLeadershipService implements LeadershipService, | ... | @@ -107,8 +110,8 @@ public class HazelcastLeadershipService implements LeadershipService, |
| 107 | private final Map<String, Topic> topics = Maps.newConcurrentMap(); | 110 | private final Map<String, Topic> topics = Maps.newConcurrentMap(); |
| 108 | private NodeId localNodeId; | 111 | private NodeId localNodeId; |
| 109 | 112 | ||
| 110 | - private ITopic<byte[]> leaderTopic; | 113 | + private static final MessageSubject LEADERSHIP_EVENT_MESSAGE_SUBJECT = |
| 111 | - private String leaderTopicRegistrationId; | 114 | + new MessageSubject("hz-leadership-events"); |
| 112 | 115 | ||
| 113 | @Activate | 116 | @Activate |
| 114 | protected void activate() { | 117 | protected void activate() { |
| ... | @@ -120,8 +123,8 @@ public class HazelcastLeadershipService implements LeadershipService, | ... | @@ -120,8 +123,8 @@ public class HazelcastLeadershipService implements LeadershipService, |
| 120 | topicConfig.setGlobalOrderingEnabled(true); | 123 | topicConfig.setGlobalOrderingEnabled(true); |
| 121 | topicConfig.setName(TOPIC_HZ_ID); | 124 | topicConfig.setName(TOPIC_HZ_ID); |
| 122 | storeService.getHazelcastInstance().getConfig().addTopicConfig(topicConfig); | 125 | storeService.getHazelcastInstance().getConfig().addTopicConfig(topicConfig); |
| 123 | - leaderTopic = storeService.getHazelcastInstance().getTopic(TOPIC_HZ_ID); | 126 | + |
| 124 | - leaderTopicRegistrationId = leaderTopic.addMessageListener(this); | 127 | + clusterCommunicator.addSubscriber(LEADERSHIP_EVENT_MESSAGE_SUBJECT, new InternalLeadershipEventListener()); |
| 125 | 128 | ||
| 126 | log.info("Hazelcast Leadership Service started"); | 129 | log.info("Hazelcast Leadership Service started"); |
| 127 | } | 130 | } |
| ... | @@ -129,7 +132,7 @@ public class HazelcastLeadershipService implements LeadershipService, | ... | @@ -129,7 +132,7 @@ public class HazelcastLeadershipService implements LeadershipService, |
| 129 | @Deactivate | 132 | @Deactivate |
| 130 | protected void deactivate() { | 133 | protected void deactivate() { |
| 131 | eventDispatcher.removeSink(LeadershipEvent.class); | 134 | eventDispatcher.removeSink(LeadershipEvent.class); |
| 132 | - leaderTopic.removeMessageListener(leaderTopicRegistrationId); | 135 | + clusterCommunicator.removeSubscriber(LEADERSHIP_EVENT_MESSAGE_SUBJECT); |
| 133 | 136 | ||
| 134 | for (Topic topic : topics.values()) { | 137 | for (Topic topic : topics.values()) { |
| 135 | topic.stop(); | 138 | topic.stop(); |
| ... | @@ -194,35 +197,6 @@ public class HazelcastLeadershipService implements LeadershipService, | ... | @@ -194,35 +197,6 @@ public class HazelcastLeadershipService implements LeadershipService, |
| 194 | listenerRegistry.removeListener(listener); | 197 | listenerRegistry.removeListener(listener); |
| 195 | } | 198 | } |
| 196 | 199 | ||
| 197 | - @Override | ||
| 198 | - public void onMessage(Message<byte[]> message) { | ||
| 199 | - LeadershipEvent leadershipEvent = | ||
| 200 | - SERIALIZER.decode(message.getMessageObject()); | ||
| 201 | - | ||
| 202 | - log.trace("Leadership Event: time = {} type = {} event = {}", | ||
| 203 | - leadershipEvent.time(), leadershipEvent.type(), | ||
| 204 | - leadershipEvent); | ||
| 205 | - | ||
| 206 | - // | ||
| 207 | - // If there is no entry for the topic, then create a new one to | ||
| 208 | - // keep track of the leadership, but don't run for leadership itself. | ||
| 209 | - // | ||
| 210 | - String topicName = leadershipEvent.subject().topic(); | ||
| 211 | - Topic topic = topics.get(topicName); | ||
| 212 | - if (topic == null) { | ||
| 213 | - topic = new Topic(topicName); | ||
| 214 | - Topic oldTopic = topics.putIfAbsent(topicName, topic); | ||
| 215 | - if (oldTopic == null) { | ||
| 216 | - // encountered new topic, start periodic processing | ||
| 217 | - topic.start(); | ||
| 218 | - } else { | ||
| 219 | - topic = oldTopic; | ||
| 220 | - } | ||
| 221 | - } | ||
| 222 | - topic.receivedLeadershipEvent(leadershipEvent); | ||
| 223 | - eventDispatcher.post(leadershipEvent); | ||
| 224 | - } | ||
| 225 | - | ||
| 226 | /** | 200 | /** |
| 227 | * Class for keeping per-topic information. | 201 | * Class for keeping per-topic information. |
| 228 | */ | 202 | */ |
| ... | @@ -406,7 +380,12 @@ public class HazelcastLeadershipService implements LeadershipService, | ... | @@ -406,7 +380,12 @@ public class HazelcastLeadershipService implements LeadershipService, |
| 406 | LeadershipEvent.Type.LEADER_REELECTED, | 380 | LeadershipEvent.Type.LEADER_REELECTED, |
| 407 | new Leadership(topicName, localNodeId, myLastLeaderTerm)); | 381 | new Leadership(topicName, localNodeId, myLastLeaderTerm)); |
| 408 | // Dispatch to all instances | 382 | // Dispatch to all instances |
| 409 | - leaderTopic.publish(SERIALIZER.encode(leadershipEvent)); | 383 | + |
| 384 | + clusterCommunicator.broadcastIncludeSelf( | ||
| 385 | + new ClusterMessage( | ||
| 386 | + clusterService.getLocalNode().id(), | ||
| 387 | + LEADERSHIP_EVENT_MESSAGE_SUBJECT, | ||
| 388 | + SERIALIZER.encode(leadershipEvent))); | ||
| 410 | } else { | 389 | } else { |
| 411 | // | 390 | // |
| 412 | // Test if time to expire a stale leader | 391 | // Test if time to expire a stale leader |
| ... | @@ -473,7 +452,11 @@ public class HazelcastLeadershipService implements LeadershipService, | ... | @@ -473,7 +452,11 @@ public class HazelcastLeadershipService implements LeadershipService, |
| 473 | leadershipEvent = new LeadershipEvent( | 452 | leadershipEvent = new LeadershipEvent( |
| 474 | LeadershipEvent.Type.LEADER_ELECTED, | 453 | LeadershipEvent.Type.LEADER_ELECTED, |
| 475 | new Leadership(topicName, localNodeId, myLastLeaderTerm)); | 454 | new Leadership(topicName, localNodeId, myLastLeaderTerm)); |
| 476 | - leaderTopic.publish(SERIALIZER.encode(leadershipEvent)); | 455 | + clusterCommunicator.broadcastIncludeSelf( |
| 456 | + new ClusterMessage( | ||
| 457 | + clusterService.getLocalNode().id(), | ||
| 458 | + LEADERSHIP_EVENT_MESSAGE_SUBJECT, | ||
| 459 | + SERIALIZER.encode(leadershipEvent))); | ||
| 477 | } | 460 | } |
| 478 | 461 | ||
| 479 | // Sleep forever until interrupted | 462 | // Sleep forever until interrupted |
| ... | @@ -497,7 +480,11 @@ public class HazelcastLeadershipService implements LeadershipService, | ... | @@ -497,7 +480,11 @@ public class HazelcastLeadershipService implements LeadershipService, |
| 497 | leadershipEvent = new LeadershipEvent( | 480 | leadershipEvent = new LeadershipEvent( |
| 498 | LeadershipEvent.Type.LEADER_BOOTED, | 481 | LeadershipEvent.Type.LEADER_BOOTED, |
| 499 | new Leadership(topicName, localNodeId, myLastLeaderTerm)); | 482 | new Leadership(topicName, localNodeId, myLastLeaderTerm)); |
| 500 | - leaderTopic.publish(SERIALIZER.encode(leadershipEvent)); | 483 | + clusterCommunicator.broadcastIncludeSelf( |
| 484 | + new ClusterMessage( | ||
| 485 | + clusterService.getLocalNode().id(), | ||
| 486 | + LEADERSHIP_EVENT_MESSAGE_SUBJECT, | ||
| 487 | + SERIALIZER.encode(leadershipEvent))); | ||
| 501 | leaderLock.unlock(); | 488 | leaderLock.unlock(); |
| 502 | } | 489 | } |
| 503 | } | 490 | } |
| ... | @@ -515,4 +502,35 @@ public class HazelcastLeadershipService implements LeadershipService, | ... | @@ -515,4 +502,35 @@ public class HazelcastLeadershipService implements LeadershipService, |
| 515 | oldTerm, newTerm); | 502 | oldTerm, newTerm); |
| 516 | } | 503 | } |
| 517 | } | 504 | } |
| 505 | + | ||
| 506 | + private class InternalLeadershipEventListener implements ClusterMessageHandler { | ||
| 507 | + | ||
| 508 | + @Override | ||
| 509 | + public void handle(ClusterMessage message) { | ||
| 510 | + LeadershipEvent leadershipEvent = | ||
| 511 | + SERIALIZER.decode(message.payload()); | ||
| 512 | + | ||
| 513 | + log.trace("Leadership Event: time = {} type = {} event = {}", | ||
| 514 | + leadershipEvent.time(), leadershipEvent.type(), | ||
| 515 | + leadershipEvent); | ||
| 516 | + // | ||
| 517 | + // If there is no entry for the topic, then create a new one to | ||
| 518 | + // keep track of the leadership, but don't run for leadership itself. | ||
| 519 | + // | ||
| 520 | + String topicName = leadershipEvent.subject().topic(); | ||
| 521 | + Topic topic = topics.get(topicName); | ||
| 522 | + if (topic == null) { | ||
| 523 | + topic = new Topic(topicName); | ||
| 524 | + Topic oldTopic = topics.putIfAbsent(topicName, topic); | ||
| 525 | + if (oldTopic == null) { | ||
| 526 | + // encountered new topic, start periodic processing | ||
| 527 | + topic.start(); | ||
| 528 | + } else { | ||
| 529 | + topic = oldTopic; | ||
| 530 | + } | ||
| 531 | + } | ||
| 532 | + topic.receivedLeadershipEvent(leadershipEvent); | ||
| 533 | + eventDispatcher.post(leadershipEvent); | ||
| 534 | + } | ||
| 535 | + } | ||
| 518 | } | 536 | } | ... | ... |
-
Please register or login to post a comment