Browse Source

Prevent Confusing Blocked Thread Warnings in MockNioTransport (#44356)

* Prevent Confusing Blocked Thread Warnings in MockNioTransport

* We can run into a race where the stacktrace collection and subsequent logging happens after the thread has already unblocked thus logging a confusing stacktrace of wherever the transport thread was after it became unblocked
* Fixed this by comparing whether or not the recorded timestamp is still the same before and after the stacktrace was recorded and not logging if it already changed
Armin Braun 6 years ago
parent
commit
6f5ea6c953

+ 9 - 6
test/framework/src/main/java/org/elasticsearch/transport/nio/MockNioTransport.java

@@ -376,14 +376,17 @@ public class MockNioTransport extends TcpTransport {
 
         private void logLongRunningExecutions() {
             for (Map.Entry<Thread, Long> entry : registry.entrySet()) {
-                final long elapsedTimeInNanos = threadPool.relativeTimeInNanos() - entry.getValue();
+                final Long blockedSinceInNanos = entry.getValue();
+                final long elapsedTimeInNanos = threadPool.relativeTimeInNanos() - blockedSinceInNanos;
                 if (elapsedTimeInNanos > warnThreshold) {
                     final Thread thread = entry.getKey();
-                    logger.warn("Potentially blocked execution on network thread [{}] [{}] [{} milliseconds]: \n{}",
-                        thread.getName(),
-                        thread.getState(),
-                        TimeUnit.NANOSECONDS.toMillis(elapsedTimeInNanos),
-                        Arrays.stream(thread.getStackTrace()).map(Object::toString).collect(Collectors.joining("\n")));
+                    final String stackTrace =
+                        Arrays.stream(thread.getStackTrace()).map(Object::toString).collect(Collectors.joining("\n"));
+                    final Thread.State threadState = thread.getState();
+                    if (blockedSinceInNanos == registry.get(thread)) {
+                        logger.warn("Potentially blocked execution on network thread [{}] [{}] [{} milliseconds]: \n{}",
+                            thread.getName(), threadState, TimeUnit.NANOSECONDS.toMillis(elapsedTimeInNanos), stackTrace);
+                    }
                 }
             }
             if (stopped == false) {