blob: 6aa8aaafb0256a0e51cc72bc4c9fbd2b130f5327 [file] [log] [blame]
Madan Jampani47b80ba2016-01-31 23:05:55 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Madan Jampani47b80ba2016-01-31 23:05:55 -08003 *
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 */
16package org.onosproject.store.service;
17
18import java.util.Map;
19import java.util.concurrent.CompletableFuture;
20import java.util.function.Consumer;
21
22import org.onosproject.cluster.Leadership;
23import org.onosproject.cluster.NodeId;
24import org.onosproject.event.Change;
Madan Jampani39fff102016-02-14 13:17:28 -080025import org.onosproject.store.primitives.DefaultLeaderElector;
Madan Jampani47b80ba2016-01-31 23:05:55 -080026
27/**
28 * Distributed mutual exclusion primitive.
29 * <p>
30 * {@code AsyncLeaderElector} facilitates mutually exclusive access to a shared resource by various cluster members.
31 * Each resource is identified by a unique topic name and members register their desire to access the resource by
32 * calling the {@link AsyncLeaderElector#run run} method. Access is grated on a FIFO basis. An instance can
33 * unregister itself from the leadership election by calling {@link AsyncLeaderElector#withdraw withdraw} method.
34 * If an instance currently holding the resource dies then the next instance waiting to be leader (in FIFO order)
35 * will be automatically granted access to the resource.
36 * <p>
37 * One can register listeners to be notified when a leadership change occurs. The Listeners are notified via a
38 * {@link Leadership} {@link Change change} subject.
39 * <p>
40 * Additionally, {@code AsyncLeaderElector} provides methods to query the current state of leadership for topics.
41 * <p>
42 * All methods of this interface return a {@link CompletableFuture future} immediately after a successful invocation.
43 * The operation itself is executed asynchronous and the returned future will be
44 * {@link CompletableFuture#complete completed} when the operation finishes.
45 */
46public interface AsyncLeaderElector extends DistributedPrimitive {
47
48 @Override
Madan Jampani39fff102016-02-14 13:17:28 -080049 default DistributedPrimitive.Type primitiveType() {
Madan Jampani47b80ba2016-01-31 23:05:55 -080050 return DistributedPrimitive.Type.LEADER_ELECTOR;
51 }
52
53 /**
54 * Attempts to become leader for a topic.
55 * @param topic leadership topic
56 * @param nodeId instance identifier of the node
57 * @return CompletableFuture that is completed with the current Leadership state of the topic
58 */
59 CompletableFuture<Leadership> run(String topic, NodeId nodeId);
60
61 /**
62 * Withdraws from leadership race for a topic.
63 * @param topic leadership topic
64 * @return CompletableFuture that is completed when the withdraw is done
65 */
66 CompletableFuture<Void> withdraw(String topic);
67
68 /**
69 * Attempts to promote a node to leadership displacing the current leader.
70 * @param topic leadership topic
71 * @param nodeId instance identifier of the new leader
72 * @return CompletableFuture that is completed with a boolean when the operation is done. Boolean is true if
73 * leadership transfer was successfully executed; false if it failed. This operation can fail (i.e. return false)
74 * if the node to be made new leader is not registering to run for election for the topic.
75 */
76 CompletableFuture<Boolean> anoint(String topic, NodeId nodeId);
77
78 /**
Madan Jampani0c0cdc62016-02-22 16:54:06 -080079 * Attempts to evict a node from all leadership elections it is registered for.
80 * <p>
81 * If the node is the current leader for a topic, this call will promote the next top candidate
82 * (if one exists) to leadership.
83 *
84 * @param nodeId node instance identifier
85 * @return CompletableFuture that is completed when the operation is done.
86 */
87 CompletableFuture<Void> evict(NodeId nodeId);
88
89 /**
90 * Attempts to promote a node to top of candidate list without displacing the current leader.
91 *
92 * @param topic leadership topic
93 * @param nodeId instance identifier of the new top candidate
94 * @return CompletableFuture that is completed with a boolean when the operation is done. Boolean is true if
95 * node is now the top candidate. This operation can fail (i.e. return false) if the node
96 * is not registered to run for election for the topic.
97 */
98 CompletableFuture<Boolean> promote(String topic, NodeId nodeId);
99
100 /**
Madan Jampani47b80ba2016-01-31 23:05:55 -0800101 * Returns the {@link Leadership} for the specified topic.
102 * @param topic leadership topic
103 * @return CompletableFuture that is completed with the current Leadership state of the topic
104 */
105 CompletableFuture<Leadership> getLeadership(String topic);
106
107 /**
108 * Returns the current {@link Leadership}s for all topics.
109 * @return CompletableFuture that is completed with the topic to Leadership mapping
110 */
111 CompletableFuture<Map<String, Leadership>> getLeaderships();
112
113 /**
114 * Registers a listener to be notified of Leadership changes for all topics.
115 * @param consumer listener to notify
116 * @return CompletableFuture that is completed when the operation completes
117 */
118 CompletableFuture<Void> addChangeListener(Consumer<Change<Leadership>> consumer);
119
120 /**
121 * Unregisters a previously registered change notification listener.
122 * <p>
123 * If the specified listener was not previously registered, this operation will be a noop.
124 * @param consumer listener to remove
125 * @return CompletableFuture that is completed when the operation completes
126 */
127 CompletableFuture<Void> removeChangeListener(Consumer<Change<Leadership>> consumer);
Madan Jampani39fff102016-02-14 13:17:28 -0800128
129 /**
130 * Returns a new {@link LeaderElector} that is backed by this instance.
131 *
132 * @param timeoutMillis timeout duration for the returned LeaderElector operations
133 * @return new {@code LeaderElector} instance
134 */
135 default LeaderElector asLeaderElector(long timeoutMillis) {
136 return new DefaultLeaderElector(this, timeoutMillis);
137 }
138
139 /**
140 * Returns a new {@link LeaderElector} that is backed by this instance and with a default operation timeout.
141 *
142 * @return new {@code LeaderElector} instance
143 */
144 default LeaderElector asLeaderElector() {
Madan Jampani3a9911c2016-02-21 11:25:45 -0800145 return asLeaderElector(Long.MAX_VALUE);
Madan Jampani39fff102016-02-14 13:17:28 -0800146 }
Madan Jampani47b80ba2016-01-31 23:05:55 -0800147}