]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9525 make CeWorkerImpl alter thread name with its details
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Thu, 6 Jul 2017 13:17:04 +0000 (15:17 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 17 Jul 2017 08:52:47 +0000 (10:52 +0200)
will allow more accurate and easier debugging when looking at thread dumps

server/sonar-ce/src/main/java/org/sonar/ce/taskprocessor/CeWorkerImpl.java
server/sonar-ce/src/test/java/org/sonar/ce/taskprocessor/CeWorkerImplTest.java

index 44034a70cfc7957a4339083cc534c436707077e0..4dbada7fce402196bad8e72795c5e07054aab709 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.ce.taskprocessor;
 
 import java.util.Optional;
+import java.util.function.Supplier;
 import javax.annotation.Nullable;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
@@ -55,6 +56,10 @@ public class CeWorkerImpl implements CeWorker {
 
   @Override
   public Result call() throws Exception {
+    return withCustomizedThreadName(this::findAndProcessTask);
+  }
+
+  private Result findAndProcessTask() {
     Optional<CeTask> ceTask = tryAndFindTaskToExecute();
     if (!ceTask.isPresent()) {
       return NO_TASK;
@@ -68,6 +73,17 @@ public class CeWorkerImpl implements CeWorker {
     return TASK_PROCESSED;
   }
 
+  private <T> T withCustomizedThreadName(Supplier<T> supplier) {
+    Thread currentThread = Thread.currentThread();
+    String oldName = currentThread.getName();
+    try {
+      currentThread.setName(String.format("Worker %s (UUID=%s) on %s", getOrdinal(), getUUID(), oldName));
+      return supplier.get();
+    } finally {
+      currentThread.setName(oldName);
+    }
+  }
+
   private Optional<CeTask> tryAndFindTaskToExecute() {
     try {
       return queue.peek(uuid);
index 5325f56771ada085ab5705f87ca4ddc16a9517db..59b3607ed30dcc5267e8c69a3495dedea65d9aec 100644 (file)
@@ -24,6 +24,7 @@ import java.util.Optional;
 import java.util.Random;
 import java.util.UUID;
 import javax.annotation.Nullable;
+import org.apache.commons.lang.RandomStringUtils;
 import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
@@ -237,6 +238,68 @@ public class CeWorkerImplTest {
     assertThat(logTester.logs(LoggerLevel.DEBUG)).isEmpty();
   }
 
+  @Test
+  public void call_sets_and_restores_thread_name_with_information_of_worker_when_there_is_no_task_to_process() throws Exception {
+    String threadName = RandomStringUtils.randomAlphabetic(3);
+    when(queue.peek(anyString())).thenAnswer(invocation -> {
+      assertThat(Thread.currentThread().getName())
+        .isEqualTo("Worker " + randomOrdinal + " (UUID=" + workerUuid + ") on " + threadName);
+      return Optional.empty();
+    });
+    Thread newThread = createThreadNameVerifyingThread(threadName);
+
+    newThread.start();
+    newThread.join();
+  }
+
+  @Test
+  public void call_sets_and_restores_thread_name_with_information_of_worker_when_a_task_is_processed() throws Exception {
+    String threadName = RandomStringUtils.randomAlphabetic(3);
+    when(queue.peek(anyString())).thenAnswer(invocation -> {
+      assertThat(Thread.currentThread().getName())
+        .isEqualTo("Worker " + randomOrdinal + " (UUID=" + workerUuid + ") on " + threadName);
+      return Optional.of(createCeTask("FooBar"));
+    });
+    taskProcessorRepository.setProcessorForTask(CeTaskTypes.REPORT, taskProcessor);
+    Thread newThread = createThreadNameVerifyingThread(threadName);
+
+    newThread.start();
+    newThread.join();
+  }
+
+  @Test
+  public void call_sets_and_restores_thread_name_with_information_of_worker_when_an_error_occurs() throws Exception {
+    String threadName = RandomStringUtils.randomAlphabetic(3);
+    CeTask ceTask = createCeTask("FooBar");
+    when(queue.peek(anyString())).thenAnswer(invocation -> {
+      assertThat(Thread.currentThread().getName())
+        .isEqualTo("Worker " + randomOrdinal + " (UUID=" + workerUuid + ") on " + threadName);
+      return Optional.of(ceTask);
+    });
+    taskProcessorRepository.setProcessorForTask(CeTaskTypes.REPORT, taskProcessor);
+    makeTaskProcessorFail(ceTask);
+    Thread newThread = createThreadNameVerifyingThread(threadName);
+
+    newThread.start();
+    newThread.join();
+  }
+
+  private Thread createThreadNameVerifyingThread(String threadName) {
+    return new Thread(() -> {
+      verifyUnchangedThreadName(threadName);
+      try {
+        underTest.call();
+      } catch (Exception e) {
+        throw new RuntimeException(e);
+      }
+      verifyUnchangedThreadName(threadName);
+    }, threadName);
+  }
+
+  private void verifyUnchangedThreadName(String threadName) {
+    assertThat(Thread.currentThread().getName()).isEqualTo(threadName);
+  }
+
   private void verifyWorkerUuid() {
     verify(queue).peek(workerUuidCaptor.capture());
     assertThat(workerUuidCaptor.getValue()).isEqualTo(workerUuid);