|
21 | 21 | import org.apache.flink.annotation.VisibleForTesting;
|
22 | 22 | import org.apache.flink.runtime.leaderelection.LeaderContender;
|
23 | 23 | import org.apache.flink.runtime.leaderelection.LeaderElection;
|
| 24 | +import org.apache.flink.runtime.leaderelection.LeadershipLostException; |
24 | 25 | import org.apache.flink.runtime.leaderretrieval.LeaderRetrievalListener;
|
25 | 26 | import org.apache.flink.runtime.leaderretrieval.LeaderRetrievalService;
|
26 | 27 | import org.apache.flink.util.FlinkException;
|
27 | 28 | import org.apache.flink.util.Preconditions;
|
| 29 | +import org.apache.flink.util.concurrent.Executors; |
28 | 30 | import org.apache.flink.util.concurrent.FutureUtils;
|
| 31 | +import org.apache.flink.util.function.ThrowingRunnable; |
29 | 32 |
|
30 | 33 | import org.slf4j.Logger;
|
31 | 34 | import org.slf4j.LoggerFactory;
|
@@ -244,38 +247,45 @@ private void removeContender(EmbeddedLeaderElection embeddedLeaderElection) {
|
244 | 247 | }
|
245 | 248 |
|
246 | 249 | /** Callback from leader contenders when they confirm a leader grant. */
|
| 250 | + @GuardedBy("lock") |
247 | 251 | private void confirmLeader(
|
248 | 252 | final EmbeddedLeaderElection embeddedLeaderElection,
|
249 | 253 | final UUID leaderSessionId,
|
250 | 254 | final String leaderAddress) {
|
251 |
| - synchronized (lock) { |
252 |
| - // if the leader election was shut down in the meantime, ignore this confirmation |
253 |
| - if (!embeddedLeaderElection.running || shutdown) { |
254 |
| - return; |
255 |
| - } |
256 |
| - |
257 |
| - try { |
258 |
| - // check if the confirmation is for the same grant, or whether it is a stale grant |
259 |
| - if (embeddedLeaderElection == currentLeaderProposed |
260 |
| - && currentLeaderSessionId.equals(leaderSessionId)) { |
261 |
| - LOG.info( |
262 |
| - "Received confirmation of leadership for leader {} , session={}", |
263 |
| - leaderAddress, |
264 |
| - leaderSessionId); |
265 |
| - |
266 |
| - // mark leadership |
267 |
| - currentLeaderConfirmed = embeddedLeaderElection; |
268 |
| - currentLeaderAddress = leaderAddress; |
269 |
| - currentLeaderProposed = null; |
| 255 | + Preconditions.checkState( |
| 256 | + currentLeaderProposed == embeddedLeaderElection, |
| 257 | + "The confirmLeader method should only be called when having the leadership acquired."); |
| 258 | + LOG.info( |
| 259 | + "Received confirmation of leadership for leader {} , session={}", |
| 260 | + leaderAddress, |
| 261 | + leaderSessionId); |
| 262 | + |
| 263 | + // mark leadership |
| 264 | + currentLeaderConfirmed = embeddedLeaderElection; |
| 265 | + currentLeaderAddress = leaderAddress; |
| 266 | + currentLeaderProposed = null; |
| 267 | + |
| 268 | + // notify all listeners |
| 269 | + notifyAllListeners(leaderAddress, leaderSessionId); |
| 270 | + } |
270 | 271 |
|
271 |
| - // notify all listeners |
272 |
| - notifyAllListeners(leaderAddress, leaderSessionId); |
273 |
| - } else { |
274 |
| - LOG.debug( |
275 |
| - "Received confirmation of leadership for a stale leadership grant. Ignoring."); |
| 272 | + private void runAsLeader( |
| 273 | + EmbeddedLeaderElection embeddedLeaderElection, |
| 274 | + UUID leaderSessionId, |
| 275 | + ThrowingRunnable<? extends Throwable> runnable) |
| 276 | + throws LeadershipLostException { |
| 277 | + synchronized (lock) { |
| 278 | + if (embeddedLeaderElection.running |
| 279 | + && !shutdown |
| 280 | + && embeddedLeaderElection.isLeader |
| 281 | + && currentLeaderSessionId.equals(leaderSessionId)) { |
| 282 | + try { |
| 283 | + runnable.run(); |
| 284 | + } catch (Throwable t) { |
| 285 | + fatalError(t); |
276 | 286 | }
|
277 |
| - } catch (Throwable t) { |
278 |
| - fatalError(t); |
| 287 | + } else { |
| 288 | + throw new LeadershipLostException(leaderSessionId); |
279 | 289 | }
|
280 | 290 | }
|
281 | 291 | }
|
@@ -472,8 +482,11 @@ public void confirmLeadership(UUID leaderSessionID, String leaderAddress) {
|
472 | 482 | }
|
473 | 483 |
|
474 | 484 | @Override
|
475 |
| - public boolean hasLeadership(UUID leaderSessionId) { |
476 |
| - return isLeader && leaderSessionId.equals(currentLeaderSessionId); |
| 485 | + public CompletableFuture<Void> runAsLeader( |
| 486 | + UUID leaderSessionId, ThrowingRunnable<? extends Throwable> callback) { |
| 487 | + return FutureUtils.runAsync( |
| 488 | + () -> EmbeddedLeaderService.this.runAsLeader(this, leaderSessionId, callback), |
| 489 | + Executors.directExecutor()); |
477 | 490 | }
|
478 | 491 |
|
479 | 492 | void shutdown(Exception cause) {
|
|
0 commit comments