![JAR search and dependency download from the Maven repository](/logo.png)
org.glowroot.instrumentation.test.harness.agent.AuxThreadContextImpl Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.glowroot.instrumentation.test.harness.agent;
import java.util.Deque;
import org.glowroot.instrumentation.test.harness.shaded.com.google.common.collect.Queues;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.glowroot.instrumentation.api.AuxThreadContext;
import org.glowroot.instrumentation.api.Getter;
import org.glowroot.instrumentation.api.Setter;
import org.glowroot.instrumentation.api.Span;
import org.glowroot.instrumentation.api.Timer;
import org.glowroot.instrumentation.engine.bytecode.api.ThreadContextPlus;
import org.glowroot.instrumentation.engine.bytecode.api.ThreadContextThreadLocal;
import org.glowroot.instrumentation.engine.impl.ImmutableTimerNameImpl;
import org.glowroot.instrumentation.engine.impl.NopTransactionService;
import org.glowroot.instrumentation.engine.impl.TimerNameImpl;
import org.glowroot.instrumentation.engine.util.TwoPartCompletion;
import org.glowroot.instrumentation.test.harness.agent.spans.IncomingSpanImpl;
import org.glowroot.instrumentation.test.harness.agent.spans.ParentSpanImpl;
public class AuxThreadContextImpl implements AuxThreadContext {
private static final TimerNameImpl AUX_THREAD_ROOT_TIMER_NAME = ImmutableTimerNameImpl.builder()
.name("auxiliary thread")
.extended(false)
.build();
private final IncomingSpanImpl incomingSpan;
private final ParentSpanImpl parentSpan;
public AuxThreadContextImpl(IncomingSpanImpl incomingSpan, ParentSpanImpl parentSpan) {
this.incomingSpan = incomingSpan;
this.parentSpan = parentSpan;
}
@Override
public Span start() {
return start(false);
}
@Override
public Span startAndMarkAsyncTransactionComplete() {
return start(true);
}
private Span start(boolean completeAsyncTransaction) {
ThreadContextThreadLocal.Holder threadContextHolder = Global.getThreadContextHolder();
ThreadContextPlus threadContext = threadContextHolder.get();
if (threadContext != null
&& ((ThreadContextImpl) threadContext).isSameParentSpan(parentSpan)) {
if (completeAsyncTransaction) {
threadContext.setTransactionAsyncComplete();
}
return NopTransactionService.LOCAL_SPAN;
}
long startNanoTime = System.nanoTime();
Deque currTimerStack = Queues.newArrayDeque();
TimerImpl auxThreadTimer =
TimerImpl.create(AUX_THREAD_ROOT_TIMER_NAME, startNanoTime, currTimerStack);
incomingSpan.addAuxThreadTimer(auxThreadTimer);
Deque currParentSpanStack = Queues.newArrayDeque();
currParentSpanStack.push(parentSpan);
TwoPartCompletion auxThreadAsyncCompletion = new TwoPartCompletion();
threadContext = new ThreadContextImpl(incomingSpan, currTimerStack, currParentSpanStack, 0,
0, auxThreadAsyncCompletion);
threadContextHolder.set(threadContext);
if (completeAsyncTransaction) {
threadContext.setTransactionAsyncComplete();
}
return new AuxThreadSpanImpl(threadContextHolder, auxThreadTimer, auxThreadAsyncCompletion,
incomingSpan);
}
private static class AuxThreadSpanImpl implements Span {
private final ThreadContextThreadLocal.Holder threadContextHolder;
private final TimerImpl auxThreadTimer;
private final TwoPartCompletion auxThreadAsyncCompletion;
private final IncomingSpanImpl incomingSpan;
private AuxThreadSpanImpl(ThreadContextThreadLocal.Holder threadContextHolder,
TimerImpl auxThreadTimer, TwoPartCompletion auxThreadAsyncCompletion,
IncomingSpanImpl incomingSpan) {
this.threadContextHolder = threadContextHolder;
this.auxThreadTimer = auxThreadTimer;
this.auxThreadAsyncCompletion = auxThreadAsyncCompletion;
this.incomingSpan = incomingSpan;
}
@Override
public void end() {
endInternal();
}
@Override
public void endWithLocationStackTrace(long thresholdNanos) {
endInternal();
}
@Override
public void endWithError(Throwable t) {
endInternal();
}
@Override
public Timer extend() {
throw new UnsupportedOperationException(
"extend() shouldn't be called on auxiliary thread span");
}
@Override
public @Nullable Object getMessageSupplier() {
return null;
}
@Override
@Deprecated
public void propagateToResponse(R response, Setter setter) {}
@Override
@Deprecated
public void extractFromResponse(R response, Getter getter) {}
private long endInternal() {
threadContextHolder.set(null);
auxThreadTimer.stop();
if (auxThreadAsyncCompletion.completePart2()) {
incomingSpan.setAsyncComplete();
}
return auxThreadTimer.getTotalNanos();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy