lmnr 0.7.18__tar.gz → 0.7.19__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of lmnr might be problematic. Click here for more details.

Files changed (103) hide show
  1. {lmnr-0.7.18 → lmnr-0.7.19}/PKG-INFO +1 -1
  2. {lmnr-0.7.18 → lmnr-0.7.19}/pyproject.toml +1 -1
  3. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/tracing/exporter.py +26 -5
  4. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/tracing/processor.py +52 -30
  5. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/version.py +1 -1
  6. {lmnr-0.7.18 → lmnr-0.7.19}/README.md +0 -0
  7. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/__init__.py +0 -0
  8. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/cli.py +0 -0
  9. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/.flake8 +0 -0
  10. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/__init__.py +0 -0
  11. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/decorators/__init__.py +0 -0
  12. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/litellm/__init__.py +0 -0
  13. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/litellm/utils.py +0 -0
  14. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/__init__.py +0 -0
  15. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/config.py +0 -0
  16. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/event_emitter.py +0 -0
  17. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/event_models.py +0 -0
  18. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/span_utils.py +0 -0
  19. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/streaming.py +0 -0
  20. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/utils.py +0 -0
  21. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/anthropic/version.py +0 -0
  22. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/cua_agent/__init__.py +0 -0
  23. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/cua_computer/__init__.py +0 -0
  24. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/cua_computer/utils.py +0 -0
  25. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/__init__.py +0 -0
  26. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/config.py +0 -0
  27. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/schema_utils.py +0 -0
  28. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/google_genai/utils.py +0 -0
  29. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/__init__.py +0 -0
  30. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/config.py +0 -0
  31. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/event_emitter.py +0 -0
  32. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/event_models.py +0 -0
  33. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/span_utils.py +0 -0
  34. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/utils.py +0 -0
  35. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/groq/version.py +0 -0
  36. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/langgraph/__init__.py +0 -0
  37. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/langgraph/utils.py +0 -0
  38. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/__init__.py +0 -0
  39. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/__init__.py +0 -0
  40. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/chat_wrappers.py +0 -0
  41. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/completion_wrappers.py +0 -0
  42. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/config.py +0 -0
  43. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/embeddings_wrappers.py +0 -0
  44. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/event_emitter.py +0 -0
  45. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/event_models.py +0 -0
  46. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/shared/image_gen_wrappers.py +0 -0
  47. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/utils.py +0 -0
  48. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v0/__init__.py +0 -0
  49. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/__init__.py +0 -0
  50. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/assistant_wrappers.py +0 -0
  51. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/event_handler_wrapper.py +0 -0
  52. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/v1/responses_wrappers.py +0 -0
  53. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openai/version.py +0 -0
  54. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/openhands_ai/__init__.py +0 -0
  55. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/opentelemetry/__init__.py +0 -0
  56. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/skyvern/__init__.py +0 -0
  57. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/opentelemetry/instrumentation/threading/__init__.py +0 -0
  58. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/tracing/__init__.py +0 -0
  59. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/tracing/_instrument_initializers.py +0 -0
  60. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/tracing/attributes.py +0 -0
  61. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/tracing/context.py +0 -0
  62. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/tracing/instruments.py +0 -0
  63. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/tracing/tracer.py +0 -0
  64. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/utils/__init__.py +0 -0
  65. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/utils/json_encoder.py +0 -0
  66. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/utils/package_check.py +0 -0
  67. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/opentelemetry_lib/utils/wrappers.py +0 -0
  68. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/py.typed +0 -0
  69. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/__init__.py +0 -0
  70. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/browser/__init__.py +0 -0
  71. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/browser/browser_use_cdp_otel.py +0 -0
  72. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/browser/browser_use_otel.py +0 -0
  73. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/browser/bubus_otel.py +0 -0
  74. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/browser/cdp_utils.py +0 -0
  75. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/browser/patchright_otel.py +0 -0
  76. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/browser/playwright_otel.py +0 -0
  77. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/browser/pw_utils.py +0 -0
  78. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/browser/recorder/record.umd.min.cjs +0 -0
  79. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/browser/utils.py +0 -0
  80. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/client/asynchronous/async_client.py +0 -0
  81. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/client/asynchronous/resources/__init__.py +0 -0
  82. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/client/asynchronous/resources/agent.py +0 -0
  83. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/client/asynchronous/resources/base.py +0 -0
  84. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/client/asynchronous/resources/browser_events.py +0 -0
  85. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/client/asynchronous/resources/evals.py +0 -0
  86. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/client/asynchronous/resources/evaluators.py +0 -0
  87. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/client/asynchronous/resources/tags.py +0 -0
  88. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/client/synchronous/resources/__init__.py +0 -0
  89. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/client/synchronous/resources/agent.py +0 -0
  90. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/client/synchronous/resources/base.py +0 -0
  91. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/client/synchronous/resources/browser_events.py +0 -0
  92. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/client/synchronous/resources/evals.py +0 -0
  93. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/client/synchronous/resources/evaluators.py +0 -0
  94. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/client/synchronous/resources/tags.py +0 -0
  95. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/client/synchronous/sync_client.py +0 -0
  96. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/datasets.py +0 -0
  97. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/decorators.py +0 -0
  98. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/eval_control.py +0 -0
  99. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/evaluations.py +0 -0
  100. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/laminar.py +0 -0
  101. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/log.py +0 -0
  102. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/types.py +0 -0
  103. {lmnr-0.7.18 → lmnr-0.7.19}/src/lmnr/sdk/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lmnr
3
- Version: 0.7.18
3
+ Version: 0.7.19
4
4
  Summary: Python SDK for Laminar
5
5
  Author: lmnr.ai
6
6
  Author-email: lmnr.ai <founders@lmnr.ai>
@@ -6,7 +6,7 @@
6
6
 
7
7
  [project]
8
8
  name = "lmnr"
9
- version = "0.7.18"
9
+ version = "0.7.19"
10
10
  description = "Python SDK for Laminar"
11
11
  authors = [
12
12
  { name = "lmnr.ai", email = "founders@lmnr.ai" }
@@ -1,5 +1,6 @@
1
1
  import grpc
2
2
  import re
3
+ import threading
3
4
  from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult
4
5
  from opentelemetry.sdk.trace import ReadableSpan
5
6
  from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
@@ -22,6 +23,7 @@ class LaminarSpanExporter(SpanExporter):
22
23
  headers: dict[str, str]
23
24
  timeout: float
24
25
  force_http: bool
26
+ _instance_lock: threading.RLock
25
27
 
26
28
  def __init__(
27
29
  self,
@@ -31,6 +33,7 @@ class LaminarSpanExporter(SpanExporter):
31
33
  timeout_seconds: int = 30,
32
34
  force_http: bool = False,
33
35
  ):
36
+ self._instance_lock = threading.RLock()
34
37
  url = base_url or from_env("LMNR_BASE_URL") or "https://api.lmnr.ai"
35
38
  url = url.rstrip("/")
36
39
  if match := re.search(r":(\d{1,5})$", url):
@@ -74,27 +77,45 @@ class LaminarSpanExporter(SpanExporter):
74
77
  "- set the OTEL_ENDPOINT environment variable\n"
75
78
  "- pass the base_url parameter to Laminar.initialize"
76
79
  )
80
+ self._init_instance()
77
81
 
82
+ def _init_instance(self):
83
+ # Create new instance first (outside critical section for performance)
78
84
  if self.force_http:
79
- self.instance = HTTPOTLPSpanExporter(
85
+ new_instance = HTTPOTLPSpanExporter(
80
86
  endpoint=self.endpoint,
81
87
  headers=self.headers,
82
88
  compression=HTTPCompression.Gzip,
83
89
  timeout=self.timeout,
84
90
  )
85
91
  else:
86
- self.instance = OTLPSpanExporter(
92
+ new_instance = OTLPSpanExporter(
87
93
  endpoint=self.endpoint,
88
94
  headers=self.headers,
89
95
  timeout=self.timeout,
90
96
  compression=grpc.Compression.Gzip,
91
97
  )
92
98
 
99
+ # Atomic swap with proper cleanup
100
+ with self._instance_lock:
101
+ old_instance: OTLPSpanExporter | HTTPOTLPSpanExporter | None = getattr(
102
+ self, "instance", None
103
+ )
104
+ if old_instance is not None:
105
+ try:
106
+ old_instance.shutdown()
107
+ except Exception as e:
108
+ logger.warning(f"Error shutting down old exporter instance: {e}")
109
+ self.instance = new_instance
110
+
93
111
  def export(self, spans: list[ReadableSpan]) -> SpanExportResult:
94
- return self.instance.export(spans)
112
+ with self._instance_lock:
113
+ return self.instance.export(spans)
95
114
 
96
115
  def shutdown(self) -> None:
97
- return self.instance.shutdown()
116
+ with self._instance_lock:
117
+ return self.instance.shutdown()
98
118
 
99
119
  def force_flush(self, timeout_millis: int = 30000) -> bool:
100
- return self.instance.force_flush(timeout_millis)
120
+ with self._instance_lock:
121
+ return self.instance.force_flush(timeout_millis)
@@ -1,4 +1,5 @@
1
1
  import logging
2
+ import threading
2
3
  import uuid
3
4
 
4
5
  from opentelemetry.sdk.trace.export import (
@@ -30,6 +31,8 @@ class LaminarSpanProcessor(SpanProcessor):
30
31
  __span_id_to_path: dict[int, list[str]] = {}
31
32
  __span_id_lists: dict[int, list[str]] = {}
32
33
  max_export_batch_size: int
34
+ _instance_lock: threading.RLock
35
+ _paths_lock: threading.RLock
33
36
 
34
37
  def __init__(
35
38
  self,
@@ -42,6 +45,8 @@ class LaminarSpanProcessor(SpanProcessor):
42
45
  disable_batch: bool = False,
43
46
  exporter: SpanExporter | None = None,
44
47
  ):
48
+ self._instance_lock = threading.RLock()
49
+ self._paths_lock = threading.RLock()
45
50
  self.logger = get_default_logger(__name__)
46
51
  self.max_export_batch_size = max_export_batch_size
47
52
  self.exporter = exporter or LaminarSpanExporter(
@@ -60,20 +65,25 @@ class LaminarSpanProcessor(SpanProcessor):
60
65
  )
61
66
 
62
67
  def on_start(self, span: Span, parent_context: Context | None = None):
63
- parent_span_path = list(span.attributes.get(PARENT_SPAN_PATH, tuple())) or (
64
- self.__span_id_to_path.get(span.parent.span_id) if span.parent else None
65
- )
66
- parent_span_ids_path = list(
67
- span.attributes.get(PARENT_SPAN_IDS_PATH, tuple())
68
- ) or (self.__span_id_lists.get(span.parent.span_id, []) if span.parent else [])
69
- span_path = parent_span_path + [span.name] if parent_span_path else [span.name]
70
- span_ids_path = parent_span_ids_path + [
71
- str(uuid.UUID(int=span.get_span_context().span_id))
72
- ]
73
- span.set_attribute(SPAN_PATH, span_path)
74
- span.set_attribute(SPAN_IDS_PATH, span_ids_path)
75
- self.__span_id_to_path[span.get_span_context().span_id] = span_path
76
- self.__span_id_lists[span.get_span_context().span_id] = span_ids_path
68
+ with self._paths_lock:
69
+ parent_span_path = list(span.attributes.get(PARENT_SPAN_PATH, tuple())) or (
70
+ self.__span_id_to_path.get(span.parent.span_id) if span.parent else None
71
+ )
72
+ parent_span_ids_path = list(
73
+ span.attributes.get(PARENT_SPAN_IDS_PATH, tuple())
74
+ ) or (
75
+ self.__span_id_lists.get(span.parent.span_id, []) if span.parent else []
76
+ )
77
+ span_path = (
78
+ parent_span_path + [span.name] if parent_span_path else [span.name]
79
+ )
80
+ span_ids_path = parent_span_ids_path + [
81
+ str(uuid.UUID(int=span.get_span_context().span_id))
82
+ ]
83
+ span.set_attribute(SPAN_PATH, span_path)
84
+ span.set_attribute(SPAN_IDS_PATH, span_ids_path)
85
+ self.__span_id_to_path[span.get_span_context().span_id] = span_path
86
+ self.__span_id_lists[span.get_span_context().span_id] = span_ids_path
77
87
 
78
88
  span.set_attribute(SPAN_INSTRUMENTATION_SOURCE, "python")
79
89
  span.set_attribute(SPAN_SDK_VERSION, __version__)
@@ -84,13 +94,16 @@ class LaminarSpanProcessor(SpanProcessor):
84
94
  for key, value in graph_context.items():
85
95
  span.set_attribute(f"lmnr.association.properties.{key}", value)
86
96
 
87
- self.instance.on_start(span, parent_context)
97
+ with self._instance_lock:
98
+ self.instance.on_start(span, parent_context)
88
99
 
89
100
  def on_end(self, span: Span):
90
- self.instance.on_end(span)
101
+ with self._instance_lock:
102
+ self.instance.on_end(span)
91
103
 
92
104
  def force_flush(self, timeout_millis: int = 30000) -> bool:
93
- return self.instance.force_flush(timeout_millis)
105
+ with self._instance_lock:
106
+ return self.instance.force_flush(timeout_millis)
94
107
 
95
108
  def force_reinit(self):
96
109
  if not isinstance(self.exporter, LaminarSpanExporter):
@@ -98,23 +111,32 @@ class LaminarSpanProcessor(SpanProcessor):
98
111
  "LaminarSpanProcessor is not using LaminarSpanExporter, cannot force reinit"
99
112
  )
100
113
  return
101
- self.instance.shutdown()
102
- disable_batch = isinstance(self.instance, SimpleSpanProcessor)
103
- del self.exporter.instance
104
- del self.instance
105
114
 
115
+ # Reinitialize exporter (thread-safe, handles its own locking)
106
116
  self.exporter._init_instance()
107
- self.instance = (
108
- SimpleSpanProcessor(self.exporter)
109
- if disable_batch
110
- else BatchSpanProcessor(
111
- self.exporter, max_export_batch_size=self.max_export_batch_size
117
+
118
+ with self._instance_lock:
119
+ old_instance = self.instance
120
+ disable_batch = isinstance(old_instance, SimpleSpanProcessor)
121
+
122
+ try:
123
+ old_instance.shutdown()
124
+ except Exception as e:
125
+ self.logger.debug(f"Error shutting down old processor instance: {e}")
126
+
127
+ self.instance = (
128
+ SimpleSpanProcessor(self.exporter)
129
+ if disable_batch
130
+ else BatchSpanProcessor(
131
+ self.exporter, max_export_batch_size=self.max_export_batch_size
132
+ )
112
133
  )
113
- )
114
134
 
115
135
  def shutdown(self):
116
- self.instance.shutdown()
136
+ with self._instance_lock:
137
+ self.instance.shutdown()
117
138
 
118
139
  def clear(self):
119
- self.__span_id_to_path = {}
120
- self.__span_id_lists = {}
140
+ with self._paths_lock:
141
+ self.__span_id_to_path = {}
142
+ self.__span_id_lists = {}
@@ -3,7 +3,7 @@ import httpx
3
3
  from packaging import version
4
4
 
5
5
 
6
- __version__ = "0.7.18"
6
+ __version__ = "0.7.19"
7
7
  PYTHON_VERSION = f"{sys.version_info.major}.{sys.version_info.minor}"
8
8
 
9
9
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes