This is an automated email from the ASF dual-hosted git repository.

tompytel pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking-python.git


The following commit(s) were added to refs/heads/master by this push:
     new 161de2c  del StackedSpan, no explicit stored SpanContext (#131)
161de2c is described below

commit 161de2c5ac4c95f7d789dee13c24b009367f8b93
Author: Tomasz Pytel <[email protected]>
AuthorDate: Mon Jul 19 14:14:37 2021 -0300

    del StackedSpan, no explicit stored SpanContext (#131)
---
 skywalking/trace/context.py | 45 +++++++++++++++++++++++----------------------
 skywalking/trace/span.py    | 36 ++++++++++++++----------------------
 2 files changed, 37 insertions(+), 44 deletions(-)

diff --git a/skywalking/trace/context.py b/skywalking/trace/context.py
index f7b7440..431ff28 100644
--- a/skywalking/trace/context.py
+++ b/skywalking/trace/context.py
@@ -27,23 +27,20 @@ from skywalking.utils.counter import Counter
 try:  # attempt to use async-local instead of thread-local context and spans
     import contextvars
 
-    __local = contextvars.ContextVar('local')
-    __spans = contextvars.ContextVar('spans')  # this needs to be a per-task 
variable, can't be part of __local
+    __spans = contextvars.ContextVar('spans')
     _spans = __spans.get
     _spans_set = __spans.set  # pyre-ignore
 
-    class AsyncLocal:
-        pass
+    def _spans():  # need to do this because can't set mutable default = [] in 
contextvars.ContextVar()
+        spans = __spans.get(None)
 
-    def _local():
-        try:
-            return __local.get()
+        if spans is not None:
+            return spans
 
-        except LookupError:
-            local = AsyncLocal()
-            __local.set(local)
+        spans = []
+        __spans.set(spans)
 
-            return local
+        return spans
 
     def _spans_dup():
         spans = __spans.get()[:]
@@ -51,13 +48,16 @@ try:  # attempt to use async-local instead of thread-local 
context and spans
 
         return spans
 
+    __spans.set([])
+
 except ImportError:
     import threading
 
-    __local = threading.local()
+    class SwLocal(threading.local):
+        def __init__(self):
+            self.spans = []
 
-    def _local():
-        return __local
+    __local = SwLocal()
 
     def _spans():
         return __local.spans
@@ -147,11 +147,14 @@ class SpanContext(object):
     def stop(self, span: Span) -> bool:
         spans = _spans()
         span.finish(self.segment)
-        del spans[spans.index(span)]
+
+        try:
+            spans.remove(span)
+        except Exception:
+            pass
 
         self._nspans -= 1
         if self._nspans == 0:
-            _local().context = None
             agent.archive(self.segment)
             return True
 
@@ -248,11 +251,9 @@ class NoopContext(SpanContext):
 
 
 def get_context() -> SpanContext:
-    local = _local()
-    context = getattr(local, 'context', False)
+    spans = _spans()
 
-    if not context:
-        context = local.context = (SpanContext() if agent.connected() else 
NoopContext())
-        _spans_set([])  # XXX would be better in SpanContext.__init__() but 
for some reason doesn't work there
+    if spans:
+        return spans[len(spans) - 1].context
 
-    return context
+    return SpanContext() if agent.connected() else NoopContext()
diff --git a/skywalking/trace/span.py b/skywalking/trace/span.py
index 70c9dcb..2a473ac 100644
--- a/skywalking/trace/span.py
+++ b/skywalking/trace/span.py
@@ -46,6 +46,7 @@ class Span(ABC):
             component: Component = None,
             layer: Layer = None,
     ):
+        self._depth = 0
         self.context = context  # type: SpanContext
         self.sid = sid  # type: int
         self.pid = pid  # type: int
@@ -63,10 +64,18 @@ class Span(ABC):
         self.error_occurred = False  # type: bool
 
     def start(self):
+        self._depth += 1
+        if self._depth != 1:
+            return
+
         self.start_time = int(time.time() * 1000)
         self.context.start(self)
 
     def stop(self):
+        self._depth -= 1
+        if self._depth:
+            return False
+
         return self.context.stop(self)
 
     def finish(self, segment: 'Segment') -> bool:
@@ -125,24 +134,7 @@ class Span(ABC):
 
 
 @tostring
-class StackedSpan(Span):
-    def __init__(self, *args, **kwargs):
-        Span.__init__(self, *args, **kwargs)
-        self._depth = 0
-
-    def start(self):
-        self._depth += 1
-        if self._depth == 1:
-            Span.start(self)
-
-    def stop(self):
-        self._depth -= 1
-        if self._depth == 0:
-            Span.stop(self)
-
-
-@tostring
-class EntrySpan(StackedSpan):
+class EntrySpan(Span):
     def __init__(
             self,
             context: 'SpanContext',
@@ -153,7 +145,7 @@ class EntrySpan(StackedSpan):
             component: 'Component' = None,
             layer: 'Layer' = None,
     ):
-        StackedSpan.__init__(
+        Span.__init__(
             self,
             context,
             sid,
@@ -167,7 +159,7 @@ class EntrySpan(StackedSpan):
         self._max_depth = 0
 
     def start(self):
-        StackedSpan.start(self)
+        Span.start(self)
         self._max_depth = self._depth
         self.component = 0
         self.layer = Layer.Unknown
@@ -189,7 +181,7 @@ class EntrySpan(StackedSpan):
 
 
 @tostring
-class ExitSpan(StackedSpan):
+class ExitSpan(Span):
     def __init__(
             self,
             context: 'SpanContext',
@@ -200,7 +192,7 @@ class ExitSpan(StackedSpan):
             component: 'Component' = None,
             layer: 'Layer' = None,
     ):
-        StackedSpan.__init__(
+        Span.__init__(
             self,
             context,
             sid,

Reply via email to