Skip to content

Commit

Permalink
4.x fix status from deadlock health check if invoking the MBean fails (
Browse files Browse the repository at this point in the history
…helidon-io#9694)

* Report ERROR instead of DOWN if MBean invocation fails

* Fix confusing comment
  • Loading branch information
tjquinno authored and barchetta committed Feb 10, 2025
1 parent af893e4 commit 4dc7600
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023 Oracle and/or its affiliates.
* Copyright (c) 2018, 2025 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,6 +19,7 @@
import java.lang.System.Logger.Level;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.util.Arrays;

import io.helidon.common.NativeImageHelper;
import io.helidon.health.HealthCheck;
Expand Down Expand Up @@ -95,17 +96,22 @@ public HealthCheckResponse call() {
.build();
}

boolean noDeadLock = false;
HealthCheckResponse.Builder builder = HealthCheckResponse.builder();

try {
// Thanks to https://stackoverflow.com/questions/1102359/programmatic-deadlock-detection-in-java#1102410
noDeadLock = (threadBean.findDeadlockedThreads() == null);
long[] deadlockedThreads = threadBean.findDeadlockedThreads();
if (deadlockedThreads != null) {
builder.status(Status.DOWN);
LOGGER.log(Level.TRACE, "Health check observed deadlocked threads: " + Arrays.toString(deadlockedThreads));
}
} catch (Throwable e) {
// ThreadBean does not work - probably in native image
LOGGER.log(Level.TRACE, "Failed to find deadlocks in ThreadMXBean, ignoring this healthcheck", e);
// ThreadBean does not work - probably in native image. Report ERROR, not DOWN, because we do not know that
// there are deadlocks which DOWN should imply; we simply cannot find out.
LOGGER.log(Level.TRACE, "Error invoking ThreadMXBean to find deadlocks; cannot complete this healthcheck", e);
builder.status(Status.ERROR);
}
return HealthCheckResponse.builder()
.status(noDeadLock ? Status.UP : Status.DOWN)
.build();
return builder.build();
}
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2022 Oracle and/or its affiliates.
* Copyright (c) 2018, 2025 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -63,4 +63,13 @@ void noDeadlockDetected() {
HealthCheckResponse response = check.call();
assertThat(response.status(), is(HealthCheckResponse.Status.UP));
}

@Test

void errorInvokingMBean() {
Mockito.when(threadBean.findDeadlockedThreads()).thenThrow(new RuntimeException("Simulated error invoking MBean"));
DeadlockHealthCheck check = new DeadlockHealthCheck(threadBean);
HealthCheckResponse response = check.call();
assertThat(response.status(), is(HealthCheckResponse.Status.ERROR));
}
}

0 comments on commit 4dc7600

Please sign in to comment.