Wrapping ExecutorService in its own representation
without this change ExecutorService was treated as an Executor and wrapped in the Executor bean. Due to this the bean was missing / bean of invalid type was registered. with this change we do not wrap ExecutorService with a Executor bean, instead we wrap it in a TraceableExecutorService representation. fixes #445
This commit is contained in:
@@ -598,11 +598,11 @@ a modified file in the correct place. Just commit it and push the change.
|
||||
If you don't have an IDE preference we would recommend that you use
|
||||
http://www.springsource.com/developer/sts[Spring Tools Suite] or
|
||||
http://eclipse.org[Eclipse] when working with the code. We use the
|
||||
http://eclipse.org/m2e/[m2eclipe] eclipse plugin for maven support. Other IDEs and tools
|
||||
http://eclipse.org/m2e/[m2eclipse] eclipse plugin for maven support. Other IDEs and tools
|
||||
should also work without issue as long as they use Maven 3.3.3 or better.
|
||||
|
||||
==== Importing into eclipse with m2eclipse
|
||||
We recommend the http://eclipse.org/m2e/[m2eclipe] eclipse plugin when working with
|
||||
We recommend the http://eclipse.org/m2e/[m2eclipse] eclipse plugin when working with
|
||||
eclipse. If you don't already have m2eclipse installed it is available from the "eclipse
|
||||
marketplace".
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.cloud.sleuth.instrument.async;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
@@ -43,8 +44,11 @@ class TraceExecutorBeanPostProcessor implements BeanPostProcessor {
|
||||
if (bean instanceof ThreadPoolTaskExecutor && !(bean instanceof TaskScheduler) &&
|
||||
!(bean instanceof LazyTraceThreadPoolTaskExecutor)) {
|
||||
return new LazyTraceThreadPoolTaskExecutor(this.beanFactory, (ThreadPoolTaskExecutor) bean);
|
||||
} else if (bean instanceof Executor && !(bean instanceof TaskScheduler) && !(bean instanceof LazyTraceExecutor)) {
|
||||
} else if (bean instanceof Executor && !(bean instanceof ExecutorService) &&
|
||||
!(bean instanceof TaskScheduler) && !(bean instanceof LazyTraceExecutor)) {
|
||||
return new LazyTraceExecutor(this.beanFactory, (Executor) bean);
|
||||
} else if (bean instanceof ExecutorService) {
|
||||
return new TraceableExecutorService(this.beanFactory, (ExecutorService) bean);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.cloud.sleuth.SpanNamer;
|
||||
import org.springframework.cloud.sleuth.TraceKeys;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
@@ -36,17 +37,24 @@ import org.springframework.cloud.sleuth.Tracer;
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class TraceableExecutorService implements ExecutorService {
|
||||
final ExecutorService delegate;
|
||||
final Tracer tracer;
|
||||
ExecutorService delegate;
|
||||
Tracer tracer;
|
||||
private final String spanName;
|
||||
final TraceKeys traceKeys;
|
||||
final SpanNamer spanNamer;
|
||||
TraceKeys traceKeys;
|
||||
SpanNamer spanNamer;
|
||||
BeanFactory beanFactory;
|
||||
|
||||
public TraceableExecutorService(final ExecutorService delegate, final Tracer tracer,
|
||||
TraceKeys traceKeys, SpanNamer spanNamer) {
|
||||
this(delegate, tracer, traceKeys, spanNamer, null);
|
||||
}
|
||||
|
||||
public TraceableExecutorService(BeanFactory beanFactory, final ExecutorService delegate) {
|
||||
this.delegate = delegate;
|
||||
this.beanFactory = beanFactory;
|
||||
this.spanName = null;
|
||||
}
|
||||
|
||||
public TraceableExecutorService(final ExecutorService delegate, final Tracer tracer,
|
||||
TraceKeys traceKeys, SpanNamer spanNamer, String spanName) {
|
||||
this.delegate = delegate;
|
||||
@@ -58,8 +66,8 @@ public class TraceableExecutorService implements ExecutorService {
|
||||
|
||||
@Override
|
||||
public void execute(Runnable command) {
|
||||
final Runnable r = new LocalComponentTraceRunnable(this.tracer, this.traceKeys,
|
||||
this.spanNamer, command, this.spanName);
|
||||
final Runnable r = new LocalComponentTraceRunnable(tracer(), traceKeys(),
|
||||
spanNamer(), command, this.spanName);
|
||||
this.delegate.execute(r);
|
||||
}
|
||||
|
||||
@@ -90,22 +98,22 @@ public class TraceableExecutorService implements ExecutorService {
|
||||
|
||||
@Override
|
||||
public <T> Future<T> submit(Callable<T> task) {
|
||||
Callable<T> c = new LocalComponentTraceCallable<>(this.tracer, this.traceKeys,
|
||||
this.spanNamer, this.spanName, task);
|
||||
Callable<T> c = new LocalComponentTraceCallable<>(tracer(), traceKeys(),
|
||||
spanNamer(), this.spanName, task);
|
||||
return this.delegate.submit(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Future<T> submit(Runnable task, T result) {
|
||||
Runnable r = new LocalComponentTraceRunnable(this.tracer, this.traceKeys,
|
||||
this.spanNamer, task, this.spanName);
|
||||
Runnable r = new LocalComponentTraceRunnable(tracer(), traceKeys(),
|
||||
spanNamer(), task, this.spanName);
|
||||
return this.delegate.submit(r, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<?> submit(Runnable task) {
|
||||
Runnable r = new LocalComponentTraceRunnable(this.tracer, this.traceKeys,
|
||||
this.spanNamer, task, this.spanName);
|
||||
Runnable r = new LocalComponentTraceRunnable(tracer(), traceKeys(),
|
||||
spanNamer(), task, this.spanName);
|
||||
return this.delegate.submit(r);
|
||||
}
|
||||
|
||||
@@ -135,11 +143,32 @@ public class TraceableExecutorService implements ExecutorService {
|
||||
List<Callable<T>> ts = new ArrayList<>();
|
||||
for (Callable<T> task : tasks) {
|
||||
if (!(task instanceof LocalComponentTraceCallable)) {
|
||||
ts.add(new LocalComponentTraceCallable<>(this.tracer, this.traceKeys,
|
||||
this.spanNamer, this.spanName, task));
|
||||
ts.add(new LocalComponentTraceCallable<>(tracer(), traceKeys(),
|
||||
spanNamer(), this.spanName, task));
|
||||
}
|
||||
}
|
||||
return ts;
|
||||
}
|
||||
|
||||
Tracer tracer() {
|
||||
if (this.tracer == null && this.beanFactory != null) {
|
||||
this.tracer = this.beanFactory.getBean(Tracer.class);
|
||||
}
|
||||
return this.tracer;
|
||||
}
|
||||
|
||||
TraceKeys traceKeys() {
|
||||
if (this.traceKeys == null && this.beanFactory != null) {
|
||||
this.traceKeys = this.beanFactory.getBean(TraceKeys.class);
|
||||
}
|
||||
return this.traceKeys;
|
||||
}
|
||||
|
||||
SpanNamer spanNamer() {
|
||||
if (this.spanNamer == null && this.beanFactory != null) {
|
||||
this.spanNamer = this.beanFactory.getBean(SpanNamer.class);
|
||||
}
|
||||
return this.spanNamer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ package org.springframework.cloud.sleuth.instrument.async.issues.issue410;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -36,6 +38,7 @@ import org.springframework.cloud.sleuth.Sampler;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.Tracer;
|
||||
import org.springframework.cloud.sleuth.instrument.async.LazyTraceExecutor;
|
||||
import org.springframework.cloud.sleuth.instrument.async.TraceableExecutorService;
|
||||
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -67,6 +70,10 @@ public class Issue410Tests {
|
||||
@Autowired Tracer tracer;
|
||||
@Autowired AsyncTask asyncTask;
|
||||
@Autowired RestTemplate restTemplate;
|
||||
/**
|
||||
* Related to issue #445
|
||||
*/
|
||||
@Autowired ExecutorService executorService;
|
||||
|
||||
@Test
|
||||
public void should_pass_tracing_info_for_tasks_running_without_a_pool() {
|
||||
@@ -138,6 +145,14 @@ public class Issue410Tests {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Related to issue #445
|
||||
*/
|
||||
@Test
|
||||
public void should_wrap_executor_service_in_trace_representation() {
|
||||
then(this.executorService).isInstanceOf(TraceableExecutorService.class);
|
||||
}
|
||||
|
||||
private int port() {
|
||||
return this.environment.getProperty("local.server.port", Integer.class);
|
||||
}
|
||||
@@ -148,11 +163,11 @@ public class Issue410Tests {
|
||||
@EnableAsync
|
||||
class AppConfig {
|
||||
|
||||
@Bean Sampler testSampler() {
|
||||
@Bean public Sampler testSampler() {
|
||||
return new AlwaysSampler();
|
||||
}
|
||||
|
||||
@Bean RestTemplate restTemplate() {
|
||||
@Bean public RestTemplate restTemplate() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
|
||||
@@ -281,4 +296,11 @@ class Application {
|
||||
return Span.idToHex(this.asyncTask.taskScheduler().getTraceId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Related to issue #445
|
||||
*/
|
||||
@Bean public ExecutorService executorService() {
|
||||
return Executors.newSingleThreadExecutor();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user