package org.skywalking.apm.agent.core.context;
import org.skywalking.apm.trace.Span;
import org.skywalking.apm.trace.TraceSegment;
/**
* LeafSpan is a special type of {@link Span}
*
* In rpc-client tracing scenario, one component could constitute by many other rpc-client.
* e.g Feign constitutes by okhttp, apache httpclient, etc.
*
* By having leaf concept, no need so many spans for single rpc call.
*
* @author wusheng
*/
public class LeafSpan extends Span {
private int stackDepth = 0;
/**
* Create a new span, by given span id and give startTime but no parent span id,
* No parent span id means that, this Span is the first span of the {@link TraceSegment}
*
* @param spanId given by the creator, and must be unique id in the {@link TraceSegment}
* @param operationName {@link #operationName}
* @param startTime given start time of span
*/
public LeafSpan(int spanId, String operationName, long startTime) {
super(spanId, -1, operationName, startTime);
}
/**
* Create a new span, by given span id, parent span, operationName and startTime.
* This span must belong a {@link TraceSegment}, also is a part of Distributed Trace.
*
* @param spanId given by the creator, and must be unique id in the {@link TraceSegment}
* @param parentSpan {@link Span}
* @param operationName {@link #operationName}
* @param startTime given start timestamp
*/
public LeafSpan(int spanId, Span parentSpan, String operationName, long startTime) {
super(spanId, parentSpan.getSpanId(), operationName, startTime);
}
void push() {
stackDepth++;
}
void pop() {
stackDepth--;
}
boolean isFinished() {
return stackDepth == 0;
}
@Override
public boolean isLeaf() {
return true;
}
private boolean isInOwnerContext() {
return stackDepth == 1;
}
/**
* Sets the string name for the logical operation this span represents,
* only when this is in context of the leaf span owner.
*
* @return this Span instance, for chaining
*/
@Override
public Span setOperationName(String operationName) {
if (isInOwnerContext()) {
super.setOperationName(operationName);
}
return this;
}
/**
* Set a key:value tag on the Span,
* only when this is in context of the leaf span owner.
*
* @return this Span instance, for chaining
*/
@Override
public final Span setTag(String key, String value) {
if (isInOwnerContext()) {
super.setTag(key, value);
}
return this;
}
@Override
public final Span setTag(String key, boolean value) {
if (isInOwnerContext()) {
super.setTag(key, value);
}
return this;
}
@Override
public final Span setTag(String key, Integer value) {
if (isInOwnerContext()) {
super.setTag(key, value);
}
return this;
}
}