Fix copying of LoggingContext to background threads
We used a custom ThreadFactory to copy the LoggingContext to newly created threads, but this is not sufficient since the new thread may be cached in a thread pool and then be reused to execute further tasks. We must copy the LoggingContext each time a task is executed in a background thread, not only when the background thread is created. To copy the LoggingContext when a Runnable or Callable is executed in the background we implement LoggingContext aware wrappers for them. We use 2 ways for executing tasks in background threads: 1. ExecutorService/ScheduledExecutorService 2. WorkQueue.Executor (custom executor) To ensure the copying of the LoggingContext when a task is executed in the background we now do: 1. Wrap each ExecutorService/ScheduledExecutorService with a wrapper that wraps each Runnable/Callable that is passed in with a LoggingContext aware wrapper. 2. Wrap each Runnable/Callable that is passed into WorkQueue.Executor with a LoggingContext aware wrapper. For WorkQueue.Executor we would ideally wrap the Runnable/Callable in decorateTask but the Runnable/Callable that is being executed is contained in a RunnableScheduledFuture and we cannot access it (decorateTask in ScheduledThreadPoolExecutor from which we inherit ignores the passed in Runnable and only the passed in RunnableScheduledFuture is relevant). Also overriding the newTaskFor(Runnable)/newTaskFor(Callable) methods does not work since ScheduledThreadPoolExecutor is creating tasks directly without invoking any newTaskFor method. Change-Id: I106dcdf6478c58dfa6fe1d7952a87aa16ead1a93 Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
@@ -19,7 +19,7 @@ import com.google.common.util.concurrent.MoreExecutors;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import com.google.gerrit.server.FanOutExecutor;
|
||||
import com.google.gerrit.server.git.WorkQueue;
|
||||
import com.google.gerrit.server.logging.LoggingContextAwareThreadFactory;
|
||||
import com.google.gerrit.server.logging.LoggingContextAwareExecutorService;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Singleton;
|
||||
@@ -83,18 +83,18 @@ public class SysExecutorModule extends AbstractModule {
|
||||
return MoreExecutors.newDirectExecutorService();
|
||||
}
|
||||
return MoreExecutors.listeningDecorator(
|
||||
MoreExecutors.getExitingExecutorService(
|
||||
new ThreadPoolExecutor(
|
||||
1,
|
||||
poolSize,
|
||||
10,
|
||||
TimeUnit.MINUTES,
|
||||
new ArrayBlockingQueue<Runnable>(poolSize),
|
||||
new ThreadFactoryBuilder()
|
||||
.setThreadFactory(new LoggingContextAwareThreadFactory())
|
||||
.setNameFormat("ChangeUpdate-%d")
|
||||
.setDaemon(true)
|
||||
.build(),
|
||||
new ThreadPoolExecutor.CallerRunsPolicy())));
|
||||
new LoggingContextAwareExecutorService(
|
||||
MoreExecutors.getExitingExecutorService(
|
||||
new ThreadPoolExecutor(
|
||||
1,
|
||||
poolSize,
|
||||
10,
|
||||
TimeUnit.MINUTES,
|
||||
new ArrayBlockingQueue<Runnable>(poolSize),
|
||||
new ThreadFactoryBuilder()
|
||||
.setNameFormat("ChangeUpdate-%d")
|
||||
.setDaemon(true)
|
||||
.build(),
|
||||
new ThreadPoolExecutor.CallerRunsPolicy()))));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user