diff --git a/pom.xml b/pom.xml index e0b49c7..1dee229 100644 --- a/pom.xml +++ b/pom.xml @@ -34,8 +34,8 @@ - 1.6 - 1.6 + 1.7 + 1.7 UTF-8 4.12 @@ -48,6 +48,7 @@ 2.10.4 0.3.4 0.1.0 + 3.0.0 @@ -91,6 +92,12 @@ ${version.junit} test + + org.awaitility + awaitility + ${version.awaitility} + test + io.opentracing opentracing-mock @@ -99,7 +106,6 @@ io.opentracing opentracing-util - test diff --git a/src/main/java/io/opentracing/contrib/concurrent/TracedCallable.java b/src/main/java/io/opentracing/contrib/concurrent/TracedCallable.java index 07200f4..027af36 100644 --- a/src/main/java/io/opentracing/contrib/concurrent/TracedCallable.java +++ b/src/main/java/io/opentracing/contrib/concurrent/TracedCallable.java @@ -3,27 +3,41 @@ import io.opentracing.Scope; import io.opentracing.Span; import io.opentracing.Tracer; +import io.opentracing.util.AutoFinishScope; +import io.opentracing.util.AutoFinishScopeManager; import java.util.concurrent.Callable; /** * @author Pavol Loffay + * @author Jose Montoya */ public class TracedCallable implements Callable { private final Callable delegate; private final Span span; private final Tracer tracer; + private final AutoFinishScope.Continuation cont; public TracedCallable(Callable delegate, Tracer tracer) { this.delegate = delegate; this.tracer = tracer; this.span = tracer.activeSpan(); + + if (tracer.scopeManager() instanceof AutoFinishScopeManager && tracer.scopeManager().active() != null) + cont = ((AutoFinishScope) tracer.scopeManager().active()).capture(); + else + cont = null; } @Override public V call() throws Exception { - Scope scope = span == null ? null : tracer.scopeManager().activate(span, false); + Scope scope = null; + if (cont != null) + scope = cont.activate(); + else if (span != null) + scope = tracer.scopeManager().activate(span, false); + try { return delegate.call(); } finally { diff --git a/src/main/java/io/opentracing/contrib/concurrent/TracedRunnable.java b/src/main/java/io/opentracing/contrib/concurrent/TracedRunnable.java index 5cd801e..9c1e045 100644 --- a/src/main/java/io/opentracing/contrib/concurrent/TracedRunnable.java +++ b/src/main/java/io/opentracing/contrib/concurrent/TracedRunnable.java @@ -3,26 +3,40 @@ import io.opentracing.Scope; import io.opentracing.Tracer; import io.opentracing.Span; +import io.opentracing.util.AutoFinishScope; +import io.opentracing.util.AutoFinishScopeManager; /** * @author Pavol Loffay + * @author Jose Montoya */ public class TracedRunnable implements Runnable { private final Runnable delegate; private final Span span; private final Tracer tracer; + private final AutoFinishScope.Continuation cont; public TracedRunnable(Runnable delegate, Tracer tracer) { this.delegate = delegate; this.tracer = tracer; this.span = tracer.activeSpan(); + + if (tracer.scopeManager() instanceof AutoFinishScopeManager && tracer.scopeManager().active() != null) + cont = ((AutoFinishScope) tracer.scopeManager().active()).capture(); + else + cont = null; } @Override public void run() { - Scope scope = span == null ? null : tracer.scopeManager().activate(span, false); - try { + Scope scope = null; + if (cont != null) + scope = cont.activate(); + else if (span != null) + scope = tracer.scopeManager().activate(span, false); + + try { delegate.run(); } finally { if (scope != null) { diff --git a/src/test/java/io/opentracing/contrib/concurrent/TracedAutoFinishTest.java b/src/test/java/io/opentracing/contrib/concurrent/TracedAutoFinishTest.java new file mode 100644 index 0000000..fdb09ed --- /dev/null +++ b/src/test/java/io/opentracing/contrib/concurrent/TracedAutoFinishTest.java @@ -0,0 +1,121 @@ +package io.opentracing.contrib.concurrent; + +import io.opentracing.Scope; +import io.opentracing.mock.MockTracer; +import io.opentracing.util.AutoFinishScopeManager; +import org.junit.Before; +import org.junit.Test; + +import java.util.concurrent.*; + +import static org.awaitility.Awaitility.await; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +/** + * @author Jose Montoya + */ +public class TracedAutoFinishTest { + private static final int NUMBER_OF_THREADS = 4; + protected MockTracer mockTracer = new MockTracer(new AutoFinishScopeManager()); + + @Before + public void before() { + mockTracer.reset(); + } + + @Test + public void autoFinishScopeExecuteTest() throws InterruptedException { + Executor executor = new TracedExecutor(Executors.newFixedThreadPool(10), mockTracer); + + try (Scope scope = mockTracer.buildSpan("auto-finish").startActive(true)){ + executor.execute(new TestRunnable()); + } + + assertNull(mockTracer.scopeManager().active()); + assertNull(mockTracer.activeSpan()); + assertEquals(0, mockTracer.finishedSpans().size()); + await().atMost(15, TimeUnit.SECONDS).until(finishedSpansSize(mockTracer), equalTo(1)); + assertEquals(1, mockTracer.finishedSpans().size()); + } + + + @Test + public void autoFinishScopeSubmitCallableTest() throws InterruptedException { + ExecutorService executorService = + new TracedExecutorService(Executors.newFixedThreadPool(NUMBER_OF_THREADS), mockTracer); + + try (Scope scope = mockTracer.buildSpan("auto-finish").startActive(true)) { + executorService.submit(new TestCallable()); + } + + assertNull(mockTracer.scopeManager().active()); + assertNull(mockTracer.activeSpan()); + assertEquals(0, mockTracer.finishedSpans().size()); + await().atMost(15, TimeUnit.SECONDS).until(finishedSpansSize(mockTracer), equalTo(1)); + assertEquals(1, mockTracer.finishedSpans().size()); + } + + @Test + public void autoFinishScopeScheduleAtFixedRateTest() throws InterruptedException { + final CountDownLatch countDownLatch = new CountDownLatch(2); + + ScheduledExecutorService executorService = + new TracedScheduledExecutorService(Executors.newScheduledThreadPool(NUMBER_OF_THREADS), mockTracer); + + try (Scope scope = mockTracer.buildSpan("auto-finish").startActive(true)){ + executorService.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + try { + Thread.sleep(300); + countDownLatch.countDown(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }, 0, 200, TimeUnit.MILLISECONDS); + } + + assertNull(mockTracer.scopeManager().active()); + assertNull(mockTracer.activeSpan()); + assertEquals(0, mockTracer.finishedSpans().size()); + countDownLatch.await(); + await().atMost(15, TimeUnit.SECONDS).until(finishedSpansSize(mockTracer), equalTo(1)); + executorService.shutdown(); + assertEquals(1, mockTracer.finishedSpans().size()); + } + + public static Callable finishedSpansSize(final MockTracer tracer) { + return new Callable() { + @Override + public Integer call() throws Exception { + return tracer.finishedSpans().size(); + } + }; + } + + class TestRunnable implements Runnable { + @Override + public void run() { + try { + Thread.sleep(300); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + class TestCallable implements Callable { + @Override + public Void call() throws Exception { + try { + Thread.sleep(300); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return null; + } + } +} \ No newline at end of file