Ayaka Koshibe
Committed by Gerrit Code Review

Fixes/improvements:

 - Leaders command uses candidateBoard keys when using -c (list candidates)
   option.
 - Bug fix for lock retry

Change-Id: I42730a85b720fc5023b9b07bef153d975c95d4df
...@@ -98,18 +98,21 @@ public class LeaderCommand extends AbstractShellCommand { ...@@ -98,18 +98,21 @@ public class LeaderCommand extends AbstractShellCommand {
98 print("--------------------------------------------------------------"); 98 print("--------------------------------------------------------------");
99 print(FMT_C, "Topic", "Leader", "Candidates"); 99 print(FMT_C, "Topic", "Leader", "Candidates");
100 print("--------------------------------------------------------------"); 100 print("--------------------------------------------------------------");
101 - leaderBoard 101 + candidates
102 - .values() 102 + .entrySet()
103 .stream() 103 .stream()
104 - .filter(l -> allTopics || pattern.matcher(l.topic()).matches()) 104 + .filter(es -> allTopics || pattern.matcher(es.getKey()).matches())
105 - .sorted(leadershipComparator) 105 + .forEach(es -> {
106 - .forEach(l -> { 106 + List<NodeId> list = es.getValue();
107 - List<NodeId> list = candidates.get(l.topic()); 107 + if (list == null || list.isEmpty()) {
108 + return;
109 + }
110 + Leadership l = leaderBoard.get(es.getKey());
108 print(FMT_C, 111 print(FMT_C,
109 - l.topic(), 112 + es.getKey(),
110 - l.leader(), 113 + l == null ? "null" : l.leader(),
111 - list.get(0).toString());
112 // formatting hacks to get it into a table 114 // formatting hacks to get it into a table
115 + list.get(0).toString());
113 list.subList(1, list.size()).forEach(n -> print(FMT_C, " ", " ", n)); 116 list.subList(1, list.size()).forEach(n -> print(FMT_C, " ", " ", n));
114 print(FMT_C, " ", " ", " "); 117 print(FMT_C, " ", " ", " ");
115 }); 118 });
...@@ -139,12 +142,32 @@ public class LeaderCommand extends AbstractShellCommand { ...@@ -139,12 +142,32 @@ public class LeaderCommand extends AbstractShellCommand {
139 return result; 142 return result;
140 } 143 }
141 144
145 + /**
146 + * Returns JSON node representing the leaders.
147 + *
148 + * @param leaderBoard map of leaders
149 + */
150 + private JsonNode json(Map<String, Leadership> leaderBoard,
151 + Map<String, List<NodeId>> candidateBoard) {
152 + ObjectMapper mapper = new ObjectMapper();
153 + ArrayNode result = mapper.createArrayNode();
154 + candidateBoard.entrySet()
155 + .stream()
156 + .forEach(es -> {
157 + Leadership l = leaderBoard.get(es.getKey());
158 + result.add(
159 + mapper.createObjectNode()
160 + .put("topic", es.getKey())
161 + .put("leader", l == null ? "none" : l.leader().toString())
162 + .put("candidates", es.getValue().toString()));
163 + });
164 + return result;
165 + }
142 166
143 @Override 167 @Override
144 protected void execute() { 168 protected void execute() {
145 LeadershipService leaderService = get(LeadershipService.class); 169 LeadershipService leaderService = get(LeadershipService.class);
146 Map<String, Leadership> leaderBoard = leaderService.getLeaderBoard(); 170 Map<String, Leadership> leaderBoard = leaderService.getLeaderBoard();
147 -
148 if (topicPattern == null) { 171 if (topicPattern == null) {
149 allTopics = true; 172 allTopics = true;
150 } else { 173 } else {
...@@ -152,12 +175,17 @@ public class LeaderCommand extends AbstractShellCommand { ...@@ -152,12 +175,17 @@ public class LeaderCommand extends AbstractShellCommand {
152 pattern = Pattern.compile(topicPattern); 175 pattern = Pattern.compile(topicPattern);
153 } 176 }
154 177
155 - if (outputJson()) { 178 + if (showCandidates) {
156 - print("%s", json(leaderBoard)); 179 + Map<String, List<NodeId>> candidates = leaderService
157 - } else { 180 + .getCandidates();
158 - if (showCandidates) { 181 + if (outputJson()) {
159 - Map<String, List<NodeId>> candidates = leaderService.getCandidates(); 182 + print("%s", json(leaderBoard, candidates));
183 + } else {
160 displayCandidates(leaderBoard, candidates); 184 displayCandidates(leaderBoard, candidates);
185 + }
186 + } else {
187 + if (outputJson()) {
188 + print("%s", json(leaderBoard));
161 } else { 189 } else {
162 displayLeaders(leaderBoard); 190 displayLeaders(leaderBoard);
163 } 191 }
......
...@@ -283,19 +283,23 @@ public class DistributedLeadershipManager implements LeadershipService { ...@@ -283,19 +283,23 @@ public class DistributedLeadershipManager implements LeadershipService {
283 if (!activeTopics.contains(path)) { 283 if (!activeTopics.contains(path)) {
284 return; 284 return;
285 } 285 }
286 - 286 + try {
287 - Versioned<List<NodeId>> candidates = candidateMap.get(path); 287 + Versioned<List<NodeId>> candidates = candidateMap.get(path);
288 - if (candidates != null) { 288 + if (candidates != null) {
289 - List<NodeId> activeNodes = candidates.value().stream() 289 + List<NodeId> activeNodes = candidates.value().stream()
290 - .filter(n -> clusterService.getState(n) == ACTIVE) 290 + .filter(n -> clusterService.getState(n) == ACTIVE)
291 - .collect(Collectors.toList()); 291 + .collect(Collectors.toList());
292 - if (localNodeId.equals(activeNodes.get(LEADER_CANDIDATE_POS))) { 292 + if (localNodeId.equals(activeNodes.get(LEADER_CANDIDATE_POS))) {
293 - leaderLockAttempt(path, candidates.value()); 293 + leaderLockAttempt(path, candidates.value());
294 + } else {
295 + retryLock(path);
296 + }
294 } else { 297 } else {
295 - retryLock(path); 298 + throw new IllegalStateException("should not be here");
296 } 299 }
297 - } else { 300 + } catch (Exception e) {
298 - throw new IllegalStateException("should not be here"); 301 + log.debug("Failed to fetch candidate information for {}", path, e);
302 + retryLock(path);
299 } 303 }
300 } 304 }
301 305
...@@ -336,7 +340,7 @@ public class DistributedLeadershipManager implements LeadershipService { ...@@ -336,7 +340,7 @@ public class DistributedLeadershipManager implements LeadershipService {
336 final MutableBoolean updated = new MutableBoolean(false); 340 final MutableBoolean updated = new MutableBoolean(false);
337 candidateBoard.compute(path, (k, current) -> { 341 candidateBoard.compute(path, (k, current) -> {
338 if (current == null || current.epoch() < newInfo.epoch()) { 342 if (current == null || current.epoch() < newInfo.epoch()) {
339 - log.info("updating candidateboard with {}", newInfo); 343 + log.debug("updating candidateboard with {}", newInfo);
340 updated.setTrue(); 344 updated.setTrue();
341 return newInfo; 345 return newInfo;
342 } 346 }
......