Repository: DataDog/dd-trace-py

Issue:
tests.internal.runtime.test_runtime_metrics.TestRuntimeWorker.test_worker_metrics fails randomly
```
    def test_worker_metrics(self):
        self.tracer.configure(collect_metrics=True)
    
        with self.override_global_tracer(self.tracer):
            self.tracer._dogstatsd_client = DogStatsd()
            self.tracer._dogstatsd_client.socket = FakeSocket()
    
            root = self.start_span('parent', service='parent')
            context = root.context
            self.start_span('child', service='child', child_of=context)
    
            self.worker = RuntimeWorker(self.tracer._dogstatsd_client)
            self.worker.start()
            self.worker.stop()
    
            # get all received metrics
            received = []
            while True:
                new = self.tracer._dogstatsd_client.socket.recv()
                if not new:
                    break
    
                received.append(new)
                # DEV: sleep since metrics will still be getting collected and written
                time.sleep(.5)
    
            # expect received all default metrics
>           self.assertEqual(len(received), len(DEFAULT_RUNTIME_METRICS))
E           AssertionError: 0 != 10

tests/internal/runtime/test_runtime_metrics.py:75: AssertionError
```

https://circleci.com/gh/DataDog/dd-trace-py/114364


Discussion:

Resolving patch:
diff --git a/ddtrace/internal/runtime/runtime_metrics.py b/ddtrace/internal/runtime/runtime_metrics.py
--- a/ddtrace/internal/runtime/runtime_metrics.py
+++ b/ddtrace/internal/runtime/runtime_metrics.py
@@ -60,10 +60,10 @@ class RuntimeWorker(object):
 
     FLUSH_INTERVAL = 10
 
-    def __init__(self, statsd_client, flush_interval=None):
+    def __init__(self, statsd_client, flush_interval=FLUSH_INTERVAL):
         self._stay_alive = None
         self._thread = None
-        self._flush_interval = flush_interval or self.FLUSH_INTERVAL
+        self._flush_interval = flush_interval
         self._statsd_client = statsd_client
         self._runtime_metrics = RuntimeMetrics()
 
@@ -85,6 +85,10 @@ def stop(self):
             log.debug('Stopping {}'.format(self))
             self._stay_alive = False
 
+    def join(self, timeout=None):
+        if self._thread:
+            return self._thread.join(timeout)
+
     def _write_metric(self, key, value):
         log.debug('Writing metric {}:{}'.format(key, value))
         self._statsd_client.gauge(key, value)


Test patch:
diff --git a/tests/internal/runtime/test_runtime_metrics.py b/tests/internal/runtime/test_runtime_metrics.py
--- a/tests/internal/runtime/test_runtime_metrics.py
+++ b/tests/internal/runtime/test_runtime_metrics.py
@@ -1,5 +1,3 @@
-import time
-
 from ddtrace.internal.runtime.runtime_metrics import (
     RuntimeTags,
     RuntimeMetrics,
@@ -56,9 +54,10 @@ def test_worker_metrics(self):
             context = root.context
             self.start_span('child', service='child', child_of=context)
 
-            self.worker = RuntimeWorker(self.tracer._dogstatsd_client)
+            self.worker = RuntimeWorker(self.tracer._dogstatsd_client, 0)
             self.worker.start()
             self.worker.stop()
+            self.worker.join()
 
             # get all received metrics
             received = []
@@ -68,8 +67,6 @@ def test_worker_metrics(self):
                     break
 
                 received.append(new)
-                # DEV: sleep since metrics will still be getting collected and written
-                time.sleep(.5)
 
             # expect received all default metrics
             self.assertEqual(len(received), len(DEFAULT_RUNTIME_METRICS))