@Test public void completeRequestSpan_marks_listener_as_completed_even_if_unexpected_exception_occurs() { Tracer.getInstance().startRequestWithRootSpan("someOtherUnrelatedSpan"); TracingState unrelatedThreadTracingState = TracingState.getCurrentThreadTracingState(); final RuntimeException expectedExplosion = new RuntimeException("kaboom"); SpanRecorder explodingSpanRecorder = new SpanRecorder() { @Override public void spanCompleted(Span span) { throw expectedExplosion; } }; Tracer.getInstance().addSpanLifecycleListener(explodingSpanRecorder); assertThat(implSpy.alreadyCompleted.get()).isFalse(); Throwable actualEx = catchThrowable(() -> implSpy.completeRequestSpan(asyncEventMock)); assertThat(actualEx).isSameAs(expectedExplosion); assertThat(explodingSpanRecorder.completedSpans).hasSize(0); assertThat(implSpy.alreadyCompleted.get()).isTrue(); assertThat(TracingState.getCurrentThreadTracingState()).isEqualTo(unrelatedThreadTracingState); }
@SuppressWarnings("deprecation") protected void completeRequestSpan(AsyncEvent event) { if (alreadyCompleted.getAndSet(true)) { return; } ServletRequest request = event.getSuppliedRequest(); ServletResponse response = event.getSuppliedResponse(); final HttpServletRequest httpRequest = (request instanceof HttpServletRequest) ? (HttpServletRequest) request : null; final HttpServletResponse httpResponse = (response instanceof HttpServletResponse) ? (HttpServletResponse) response : null; final Throwable error = event.getThrowable(); runnableWithTracing( new Runnable() { @Override public void run() { Span span = Tracer.getInstance().getCurrentSpan(); try { tagAndNamingStrategy.handleResponseTaggingAndFinalSpanName( span, httpRequest, httpResponse, error, tagAndNamingAdapter ); } finally { Tracer.getInstance().completeRequestSpan(); } } }, originalRequestTracingState ).run(); }
WingtipsRequestSpanCompletionAsyncListener implements AsyncListener { @SuppressWarnings("deprecation") protected void completeRequestSpan(AsyncEvent event) { if (alreadyCompleted.getAndSet(true)) { return; } ServletRequest request = event.getSuppliedRequest(); ServletResponse response = event.getSuppliedResponse(); final HttpServletRequest httpRequest = (request instanceof HttpServletRequest) ? (HttpServletRequest) request : null; final HttpServletResponse httpResponse = (response instanceof HttpServletResponse) ? (HttpServletResponse) response : null; final Throwable error = event.getThrowable(); runnableWithTracing( new Runnable() { @Override public void run() { Span span = Tracer.getInstance().getCurrentSpan(); try { tagAndNamingStrategy.handleResponseTaggingAndFinalSpanName( span, httpRequest, httpResponse, error, tagAndNamingAdapter ); } finally { Tracer.getInstance().completeRequestSpan(); } } }, originalRequestTracingState ).run(); } }
WingtipsRequestSpanCompletionAsyncListener implements AsyncListener { @SuppressWarnings("deprecation") protected void completeRequestSpan(AsyncEvent event) { if (alreadyCompleted.getAndSet(true)) { return; } ServletRequest request = event.getSuppliedRequest(); ServletResponse response = event.getSuppliedResponse(); final HttpServletRequest httpRequest = (request instanceof HttpServletRequest) ? (HttpServletRequest) request : null; final HttpServletResponse httpResponse = (response instanceof HttpServletResponse) ? (HttpServletResponse) response : null; final Throwable error = event.getThrowable(); runnableWithTracing( new Runnable() { @Override public void run() { Span span = Tracer.getInstance().getCurrentSpan(); try { tagAndNamingStrategy.handleResponseTaggingAndFinalSpanName( span, httpRequest, httpResponse, error, tagAndNamingAdapter ); } finally { Tracer.getInstance().completeRequestSpan(); } } }, originalRequestTracingState ).run(); } WingtipsRequestSpanCompletionAsyncListener(
        TracingState originalRequestTracingState,
        HttpTagAndSpanNamingStrategy<HttpServletRequest, HttpServletResponse> tagAndNamingStrategy,
        HttpTagAndSpanNamingAdapter<HttpServletRequest, HttpServletResponse> tagAndNamingAdapter
    ); }
WingtipsRequestSpanCompletionAsyncListener implements AsyncListener { @SuppressWarnings("deprecation") protected void completeRequestSpan(AsyncEvent event) { if (alreadyCompleted.getAndSet(true)) { return; } ServletRequest request = event.getSuppliedRequest(); ServletResponse response = event.getSuppliedResponse(); final HttpServletRequest httpRequest = (request instanceof HttpServletRequest) ? (HttpServletRequest) request : null; final HttpServletResponse httpResponse = (response instanceof HttpServletResponse) ? (HttpServletResponse) response : null; final Throwable error = event.getThrowable(); runnableWithTracing( new Runnable() { @Override public void run() { Span span = Tracer.getInstance().getCurrentSpan(); try { tagAndNamingStrategy.handleResponseTaggingAndFinalSpanName( span, httpRequest, httpResponse, error, tagAndNamingAdapter ); } finally { Tracer.getInstance().completeRequestSpan(); } } }, originalRequestTracingState ).run(); } WingtipsRequestSpanCompletionAsyncListener(
        TracingState originalRequestTracingState,
        HttpTagAndSpanNamingStrategy<HttpServletRequest, HttpServletResponse> tagAndNamingStrategy,
        HttpTagAndSpanNamingAdapter<HttpServletRequest, HttpServletResponse> tagAndNamingAdapter
    ); @Override void onComplete(AsyncEvent event); @Override void onTimeout(AsyncEvent event); @Override void onError(AsyncEvent event); @Override void onStartAsync(AsyncEvent event); }
WingtipsRequestSpanCompletionAsyncListener implements AsyncListener { @SuppressWarnings("deprecation") protected void completeRequestSpan(AsyncEvent event) { if (alreadyCompleted.getAndSet(true)) { return; } ServletRequest request = event.getSuppliedRequest(); ServletResponse response = event.getSuppliedResponse(); final HttpServletRequest httpRequest = (request instanceof HttpServletRequest) ? (HttpServletRequest) request : null; final HttpServletResponse httpResponse = (response instanceof HttpServletResponse) ? (HttpServletResponse) response : null; final Throwable error = event.getThrowable(); runnableWithTracing( new Runnable() { @Override public void run() { Span span = Tracer.getInstance().getCurrentSpan(); try { tagAndNamingStrategy.handleResponseTaggingAndFinalSpanName( span, httpRequest, httpResponse, error, tagAndNamingAdapter ); } finally { Tracer.getInstance().completeRequestSpan(); } } }, originalRequestTracingState ).run(); } WingtipsRequestSpanCompletionAsyncListener(
        TracingState originalRequestTracingState,
        HttpTagAndSpanNamingStrategy<HttpServletRequest, HttpServletResponse> tagAndNamingStrategy,
        HttpTagAndSpanNamingAdapter<HttpServletRequest, HttpServletResponse> tagAndNamingAdapter
    ); @Override void onComplete(AsyncEvent event); @Override void onTimeout(AsyncEvent event); @Override void onError(AsyncEvent event); @Override void onStartAsync(AsyncEvent event);  }