From 1ae04cf2bb1d4a2defc91633c7a453e02a0f8fea Mon Sep 17 00:00:00 2001 From: qxo <49526356@qq.com> Date: Tue, 6 Aug 2019 08:30:29 +0800 Subject: [PATCH] improve AsyncSpan API: make #asyncFinish and #prepareForAsync can not invoke more than once (#3201) * improve AsyncSpan API: make #asyncFinish and #prepareForAsync can not invoke more than once make the API more strong: make the plugin code bug fail-fast --- .../core/context/trace/AbstractTracingSpan.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/AbstractTracingSpan.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/AbstractTracingSpan.java index 4c14aa2b1..b5ece98f0 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/AbstractTracingSpan.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/AbstractTracingSpan.java @@ -40,7 +40,14 @@ public abstract class AbstractTracingSpan implements AbstractSpan { protected String operationName; protected int operationId; protected SpanLayer layer; - protected boolean isInAsyncMode = false; + /** + * The span has been tagged in async mode, required async stop to finish. + */ + protected volatile boolean isInAsyncMode = false; + /** + * The flag represents whether the span has been async stopped + */ + private volatile boolean isAsyncStopped = false; protected volatile AbstractTracerContext context; /** @@ -322,6 +329,9 @@ public abstract class AbstractTracingSpan implements AbstractSpan { } @Override public AbstractSpan prepareForAsync() { + if (isInAsyncMode) { + throw new RuntimeException("Prepare for async repeatedly. Span is already in async mode."); + } context = ContextManager.awaitFinishAsync(this); isInAsyncMode = true; return this; @@ -331,9 +341,12 @@ public abstract class AbstractTracingSpan implements AbstractSpan { if (!isInAsyncMode) { throw new RuntimeException("Span is not in async mode, please use '#prepareForAsync' to active."); } - + if (isAsyncStopped) { + throw new RuntimeException("Can not do async finish for the span repeately."); + } this.endTime = System.currentTimeMillis(); context.asyncStop(this); + isAsyncStopped = true; return this; } }