Skip to content

Commit 2d8c98d

Browse files
committed
Fix NPE issue on unreachable nodes by using optionals
1 parent b2b8b80 commit 2d8c98d

File tree

1 file changed

+34
-30
lines changed

1 file changed

+34
-30
lines changed

src/main/java/com/spotify/reaper/service/SegmentRunner.java

+34-30
Original file line numberDiff line numberDiff line change
@@ -325,18 +325,19 @@ boolean canRepair(RepairSegment segment, String keyspace, JmxProxy coordinator,
325325
for (String hostName : allHosts) {
326326
LOG.debug("checking host '{}' for pending compactions and other repairs (can repair?)"
327327
+ " Run id '{}'", hostName, segment.getRunId());
328-
JmxProxy hostProxy = null;
328+
Optional<JmxProxy> hostProxy = Optional.absent();
329329
try{
330330
Optional<HostMetrics> hostMetrics = Optional.absent();
331331
try{
332-
hostProxy = context.jmxConnectionFactory.connect(hostName);
332+
hostProxy = Optional.fromNullable(context.jmxConnectionFactory.connect(hostName));
333333
connected = true;
334-
hostMetrics = getMetricsForHost(hostName, hostProxy);
335334
}
336335
catch(Exception e) {
337-
LOG.debug("Couldn't reach host {} through JMX. Trying to collect metrics from storage...");
336+
LOG.debug("Couldn't reach host {} through JMX. Trying to collect metrics from storage...", hostName);
338337
}
339338

339+
hostMetrics = getMetricsForHost(hostName, hostProxy);
340+
340341
if(!hostMetrics.isPresent()) {
341342
gotMetricsForAllHosts = false;
342343
closeJmxConnection(hostProxy, connected);
@@ -396,43 +397,46 @@ boolean canRepair(RepairSegment segment, String keyspace, JmxProxy coordinator,
396397
return gotMetricsForAllHosts; // check if we should postpone when we cannot get all metrics, or just drop the lead
397398
}
398399

399-
private void closeJmxConnection(JmxProxy jmxProxy, boolean connected) {
400-
if(connected)
400+
private void closeJmxConnection(Optional<JmxProxy> jmxProxy, boolean connected) {
401+
if(connected && jmxProxy.isPresent())
401402
try {
402-
jmxProxy.close();
403+
jmxProxy.get().close();
403404
} catch (ReaperException e) {
404-
LOG.warn("Could not close JMX connection to {}. Potential leak...", jmxProxy.getHost());
405+
LOG.warn("Could not close JMX connection to {}. Potential leak...", jmxProxy.get().getHost());
405406
}
406407
}
407408

408-
private void handlePotentialStuckRepairs(JmxProxy hostProxy, LazyInitializer<Set<String>> busyHosts, String hostName) throws ConcurrentException {
409-
if (!busyHosts.get().contains(hostName) && context.storage.getStorageType() != StorageType.CASSANDRA) {
409+
private void handlePotentialStuckRepairs(Optional<JmxProxy> hostProxy, LazyInitializer<Set<String>> busyHosts, String hostName) throws ConcurrentException {
410+
if (!busyHosts.get().contains(hostName) && context.storage.getStorageType() != StorageType.CASSANDRA && hostProxy.isPresent()) {
410411
LOG.warn("A host ({}) reported that it is involved in a repair, but there is no record "
411412
+ "of any ongoing repair involving the host. Sending command to abort all repairs "
412-
+ "on the host.", hostProxy.getHost());
413-
hostProxy.cancelAllRepairs();
413+
+ "on the host.", hostProxy.get().getHost());
414+
hostProxy.get().cancelAllRepairs();
414415
}
415416
}
416417

417-
private Optional<HostMetrics> getMetricsForHost(String hostName, JmxProxy hostProxy) {
418-
try {
419-
int pendingCompactions = hostProxy.getPendingCompactions();
420-
boolean hasRepairRunning = hostProxy.isRepairRunning();
421-
422-
HostMetrics metrics = HostMetrics.builder().withHostAddress(hostName)
423-
.withPendingCompactions(pendingCompactions)
424-
.withHasRepairRunning(hasRepairRunning)
425-
.withActiveAnticompactions(0) // for future use
426-
.build();
427-
428-
context.storage.storeHostMetrics(metrics);
429-
430-
return Optional.fromNullable(metrics);
431-
432-
} catch(Exception e) {
433-
LOG.debug("Cannot reach node {} through JMX. Trying to get metrics from storage...", hostName, e);
434-
return context.storage.getHostMetrics(hostName);
418+
private Optional<HostMetrics> getMetricsForHost(String hostName, Optional<JmxProxy> hostProxy) {
419+
if(hostProxy.isPresent()) {
420+
try {
421+
int pendingCompactions = hostProxy.get().getPendingCompactions();
422+
boolean hasRepairRunning = hostProxy.get().isRepairRunning();
423+
424+
HostMetrics metrics = HostMetrics.builder().withHostAddress(hostName)
425+
.withPendingCompactions(pendingCompactions)
426+
.withHasRepairRunning(hasRepairRunning)
427+
.withActiveAnticompactions(0) // for future use
428+
.build();
429+
430+
context.storage.storeHostMetrics(metrics);
431+
432+
return Optional.fromNullable(metrics);
433+
434+
} catch(Exception e) {
435+
LOG.debug("Cannot reach node {} through JMX. Trying to get metrics from storage...", hostName, e);
436+
}
435437
}
438+
439+
return context.storage.getHostMetrics(hostName);
436440
}
437441

438442
private boolean IsRepairRunningOnOneNode(RepairSegment segment) {

0 commit comments

Comments
 (0)