Committed by
Ray Milkey
Fix potential race conditions in HazelcastLeadershipService
Change-Id: Iac232652155830c8e054760ea371ffb5639cf464
Showing
1 changed file
with
14 additions
and
7 deletions
... | @@ -166,8 +166,8 @@ public class HazelcastLeadershipService implements LeadershipService, | ... | @@ -166,8 +166,8 @@ public class HazelcastLeadershipService implements LeadershipService, |
166 | checkArgument(path != null); | 166 | checkArgument(path != null); |
167 | Topic topic = topics.get(path); | 167 | Topic topic = topics.get(path); |
168 | if (topic != null) { | 168 | if (topic != null) { |
169 | - topic.stop(); | ||
170 | topics.remove(path, topic); | 169 | topics.remove(path, topic); |
170 | + topic.stop(); | ||
171 | } | 171 | } |
172 | } | 172 | } |
173 | 173 | ||
... | @@ -213,6 +213,7 @@ public class HazelcastLeadershipService implements LeadershipService, | ... | @@ -213,6 +213,7 @@ public class HazelcastLeadershipService implements LeadershipService, |
213 | topic = new Topic(topicName); | 213 | topic = new Topic(topicName); |
214 | Topic oldTopic = topics.putIfAbsent(topicName, topic); | 214 | Topic oldTopic = topics.putIfAbsent(topicName, topic); |
215 | if (oldTopic == null) { | 215 | if (oldTopic == null) { |
216 | + // encountered new topic, start periodic processing | ||
216 | topic.start(); | 217 | topic.start(); |
217 | } else { | 218 | } else { |
218 | topic = oldTopic; | 219 | topic = oldTopic; |
... | @@ -285,7 +286,11 @@ public class HazelcastLeadershipService implements LeadershipService, | ... | @@ -285,7 +286,11 @@ public class HazelcastLeadershipService implements LeadershipService, |
285 | /** | 286 | /** |
286 | * Starts operation. | 287 | * Starts operation. |
287 | */ | 288 | */ |
288 | - private void start() { | 289 | + private synchronized void start() { |
290 | + if (!isShutdown) { | ||
291 | + // already running | ||
292 | + return; | ||
293 | + } | ||
289 | isShutdown = false; | 294 | isShutdown = false; |
290 | String threadPoolName = "onos-leader-election-" + topicName + "-%d"; | 295 | String threadPoolName = "onos-leader-election-" + topicName + "-%d"; |
291 | leaderElectionExecutor = Executors.newScheduledThreadPool(2, | 296 | leaderElectionExecutor = Executors.newScheduledThreadPool(2, |
... | @@ -303,13 +308,14 @@ public class HazelcastLeadershipService implements LeadershipService, | ... | @@ -303,13 +308,14 @@ public class HazelcastLeadershipService implements LeadershipService, |
303 | /** | 308 | /** |
304 | * Runs for leadership. | 309 | * Runs for leadership. |
305 | */ | 310 | */ |
306 | - private void runForLeadership() { | 311 | + private synchronized void runForLeadership() { |
307 | if (isRunningForLeadership) { | 312 | if (isRunningForLeadership) { |
308 | return; // Nothing to do: already running | 313 | return; // Nothing to do: already running |
309 | } | 314 | } |
310 | if (isShutdown) { | 315 | if (isShutdown) { |
311 | start(); | 316 | start(); |
312 | } | 317 | } |
318 | + isRunningForLeadership = true; | ||
313 | String lockHzId = "LeadershipService/" + topicName + "/lock"; | 319 | String lockHzId = "LeadershipService/" + topicName + "/lock"; |
314 | String termHzId = "LeadershipService/" + topicName + "/term"; | 320 | String termHzId = "LeadershipService/" + topicName + "/term"; |
315 | leaderLock = storeService.getHazelcastInstance().getLock(lockHzId); | 321 | leaderLock = storeService.getHazelcastInstance().getLock(lockHzId); |
... | @@ -326,7 +332,7 @@ public class HazelcastLeadershipService implements LeadershipService, | ... | @@ -326,7 +332,7 @@ public class HazelcastLeadershipService implements LeadershipService, |
326 | /** | 332 | /** |
327 | * Stops leadership election for the topic. | 333 | * Stops leadership election for the topic. |
328 | */ | 334 | */ |
329 | - private void stop() { | 335 | + private synchronized void stop() { |
330 | isShutdown = true; | 336 | isShutdown = true; |
331 | isRunningForLeadership = false; | 337 | isRunningForLeadership = false; |
332 | // getLockFuture.cancel(true); | 338 | // getLockFuture.cancel(true); |
... | @@ -454,6 +460,7 @@ public class HazelcastLeadershipService implements LeadershipService, | ... | @@ -454,6 +460,7 @@ public class HazelcastLeadershipService implements LeadershipService, |
454 | continue; | 460 | continue; |
455 | } | 461 | } |
456 | 462 | ||
463 | + try { | ||
457 | synchronized (this) { | 464 | synchronized (this) { |
458 | // | 465 | // |
459 | // This instance is now the leader | 466 | // This instance is now the leader |
... | @@ -469,7 +476,6 @@ public class HazelcastLeadershipService implements LeadershipService, | ... | @@ -469,7 +476,6 @@ public class HazelcastLeadershipService implements LeadershipService, |
469 | leaderTopic.publish(SERIALIZER.encode(leadershipEvent)); | 476 | leaderTopic.publish(SERIALIZER.encode(leadershipEvent)); |
470 | } | 477 | } |
471 | 478 | ||
472 | - try { | ||
473 | // Sleep forever until interrupted | 479 | // Sleep forever until interrupted |
474 | Thread.sleep(Long.MAX_VALUE); | 480 | Thread.sleep(Long.MAX_VALUE); |
475 | } catch (InterruptedException e) { | 481 | } catch (InterruptedException e) { |
... | @@ -479,8 +485,8 @@ public class HazelcastLeadershipService implements LeadershipService, | ... | @@ -479,8 +485,8 @@ public class HazelcastLeadershipService implements LeadershipService, |
479 | // | 485 | // |
480 | log.debug("Leader Interrupted for topic {}", | 486 | log.debug("Leader Interrupted for topic {}", |
481 | topicName); | 487 | topicName); |
482 | - } | ||
483 | 488 | ||
489 | + } finally { | ||
484 | synchronized (this) { | 490 | synchronized (this) { |
485 | // If we reach here, we should release the leadership | 491 | // If we reach here, we should release the leadership |
486 | log.debug("Leader Lock Released for topic {}", topicName); | 492 | log.debug("Leader Lock Released for topic {}", topicName); |
... | @@ -495,7 +501,8 @@ public class HazelcastLeadershipService implements LeadershipService, | ... | @@ -495,7 +501,8 @@ public class HazelcastLeadershipService implements LeadershipService, |
495 | leaderLock.unlock(); | 501 | leaderLock.unlock(); |
496 | } | 502 | } |
497 | } | 503 | } |
498 | - | 504 | + } |
505 | + isRunningForLeadership = false; | ||
499 | } | 506 | } |
500 | 507 | ||
501 | // Globally guarded by the leadership lock for this term | 508 | // Globally guarded by the leadership lock for this term | ... | ... |
-
Please register or login to post a comment