Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e68eca3

Browse files
committed
Add timeout reset and respective tests
1 parent 68b7cea commit e68eca3

File tree

4 files changed

+70
-2
lines changed

4 files changed

+70
-2
lines changed

exporter/opentelemetry-exporter-datadog/src/opentelemetry/exporter/datadog/spanprocessor.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ def worker(self):
117117
with self.condition:
118118
self.condition.wait(timeout)
119119
if not self.check_traces_queue:
120-
# spurious notification, let's wait again
120+
# spurious notification, let's wait again, reset timeout
121+
timeout = self.schedule_delay_millis / 1e3
121122
continue
122123
if self.done:
123124
# missing spans will be sent when calling flush

exporter/opentelemetry-exporter-datadog/tests/test_datadog_exporter.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,39 @@ def test_span_processor_scheduled_delay(self):
482482

483483
tracer_provider.shutdown()
484484

485+
def test_batch_span_processor_reset_timeout(self):
486+
"""Test that the scheduled timeout is reset on cycles without spans"""
487+
delay = 50
488+
exporter = MockDatadogSpanExporter()
489+
exporter._agent_writer.write.side_effect = lambda spans: time.sleep(0.05)
490+
span_processor = datadog.DatadogExportSpanProcessor(
491+
exporter, schedule_delay_millis=delay
492+
)
493+
tracer_provider = trace.TracerProvider()
494+
tracer_provider.add_span_processor(span_processor)
495+
tracer = tracer_provider.get_tracer(__name__)
496+
497+
498+
with mock.patch.object(span_processor.condition, "wait") as mock_wait:
499+
with tracer.start_span("foo"):
500+
pass
501+
502+
# give some time for exporter to loop
503+
# since wait is mocked it should return immediately
504+
time.sleep(0.1)
505+
mock_wait_calls = list(mock_wait.mock_calls)
506+
507+
# find the index of the call that processed the singular span
508+
for idx, wait_call in enumerate(mock_wait_calls):
509+
_, args, __ = wait_call
510+
if args[0] <= 0:
511+
after_calls = mock_wait_calls[idx+1:]
512+
break
513+
514+
self.assertTrue(all(args[0] >= 0.05 for _, args, __ in after_calls))
515+
516+
span_processor.shutdown()
517+
485518
def test_origin(self):
486519
context = trace_api.SpanContext(
487520
trace_id=0x000000000000000000000000DEADBEEF,

opentelemetry-sdk/src/opentelemetry/sdk/trace/export/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,8 @@ def worker(self):
210210
self.condition.wait(timeout)
211211
flush_request = self._get_and_unset_flush_request()
212212
if not self.queue:
213-
# spurious notification, let's wait again
213+
# spurious notification, let's wait again, reset timeout
214+
timeout = self.schedule_delay_millis / 1e3
214215
self._notify_flush_request_finished(flush_request)
215216
flush_request = None
216217
continue

opentelemetry-sdk/tests/trace/export/test_export.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,39 @@ def test_batch_span_processor_scheduled_delay(self):
340340

341341
span_processor.shutdown()
342342

343+
def test_batch_span_processor_reset_timeout(self):
344+
"""Test that the scheduled timeout is reset on cycles without spans"""
345+
spans_names_list = []
346+
347+
export_event = threading.Event()
348+
my_exporter = MySpanExporter(
349+
destination=spans_names_list, export_event=export_event, export_timeout_millis=50
350+
)
351+
352+
span_processor = export.BatchExportSpanProcessor(
353+
my_exporter, schedule_delay_millis=50,
354+
)
355+
356+
with mock.patch.object(span_processor.condition, "wait") as mock_wait:
357+
_create_start_and_end_span("foo", span_processor)
358+
self.assertTrue(export_event.wait(2))
359+
360+
# give some time for exporter to loop
361+
# since wait is mocked it should return immediately
362+
time.sleep(0.05)
363+
mock_wait_calls = list(mock_wait.mock_calls)
364+
365+
# find the index of the call that processed the singular span
366+
for idx, wait_call in enumerate(mock_wait_calls):
367+
_, args, __ = wait_call
368+
if args[0] <= 0:
369+
after_calls = mock_wait_calls[idx+1:]
370+
break
371+
372+
self.assertTrue(all(args[0] >= 0.05 for _, args, __ in after_calls))
373+
374+
span_processor.shutdown()
375+
343376
def test_batch_span_processor_parameters(self):
344377
# zero max_queue_size
345378
self.assertRaises(

0 commit comments

Comments
 (0)