# Path: opentracing_instrumentation/request_context.py
# def get_current_span():
#     """
#     Access current request context and extract current Span from it.
#     :return:
#         Return current span associated with the current request context.
#         If no request context is present in thread local, or the context
#         has no span, return None.
#     """
#     # Check against the old, ScopeManager-less implementation,
#     # for backwards compatibility.
#     context = RequestContextManager.current_context()
#     if context is not None:
#         return context.span
# 
#     active = opentracing.tracer.scope_manager.active
#     return active.span if active else None
# 
# def span_in_stack_context(span):
#     """
#     Create Tornado's StackContext that stores the given span in the
#     thread-local request context. This function is intended for use
#     in Tornado applications based on IOLoop, although will work fine
#     in single-threaded apps like Flask, albeit with more overhead.
# 
#     ## Usage example in Tornado application
# 
#     Suppose you have a method `handle_request(request)` in the http server.
#     Instead of calling it directly, use a wrapper:
# 
#     .. code-block:: python
# 
#         from opentracing_instrumentation import request_context
# 
#         @tornado.gen.coroutine
#         def handle_request_wrapper(request, actual_handler, *args, **kwargs)
# 
#             request_wrapper = TornadoRequestWrapper(request=request)
#             span = http_server.before_request(request=request_wrapper)
# 
#             with request_context.span_in_stack_context(span):
#                 return actual_handler(*args, **kwargs)
# 
#     :param span:
#     :return:
#         Return StackContext that wraps the request context.
#     """
# 
#     if not isinstance(opentracing.tracer.scope_manager, TornadoScopeManager):
#         raise RuntimeError('scope_manager is not TornadoScopeManager')
# 
#     # Enter the newly created stack context so we have
#     # storage available for Span activation.
#     context = tracer_stack_context()
#     entered_context = _TracerEnteredStackContext(context)
# 
#     if span is None:
#         return entered_context
# 
#     opentracing.tracer.scope_manager.activate(span, False)
#     assert opentracing.tracer.active_span is not None
#     assert opentracing.tracer.active_span is span
# 
#     return entered_context


import time
from threading import Thread
from tornado.stack_context import wrap
from opentracing_instrumentation.request_context import (
    get_current_span, span_in_stack_context,
)
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.





def test__request_context_is_thread_safe(thread_safe_tracer):
    """
    Port of Uber's internal tornado-extras (by @sema).

    This test illustrates that the default Tornado's StackContext
    is not thread-safe. The test can be made to fail by commenting
    out these lines in the ThreadSafeStackContext constructor:

        if hasattr(self, 'contexts'):
            # only patch if context exists
            self.contexts = LocalContexts()
    """

    num_iterations = 1000
    num_workers = 10
    exception = [0]

    def async_task():
        time.sleep(0.001)

# Path: opentracing_instrumentation/request_context.py
# def get_current_span():
#     """
#     Access current request context and extract current Span from it.
#     :return:
#         Return current span associated with the current request context.
#         If no request context is present in thread local, or the context
#         has no span, return None.
#     """
#     # Check against the old, ScopeManager-less implementation,
#     # for backwards compatibility.
#     context = RequestContextManager.current_context()
#     if context is not None:
#         return context.span
# 
#     active = opentracing.tracer.scope_manager.active
#     return active.span if active else None
# 
# def span_in_stack_context(span):
#     """
#     Create Tornado's StackContext that stores the given span in the
#     thread-local request context. This function is intended for use
#     in Tornado applications based on IOLoop, although will work fine
#     in single-threaded apps like Flask, albeit with more overhead.
# 
#     ## Usage example in Tornado application
# 
#     Suppose you have a method `handle_request(request)` in the http server.
#     Instead of calling it directly, use a wrapper:
# 
#     .. code-block:: python
# 
#         from opentracing_instrumentation import request_context
# 
#         @tornado.gen.coroutine
#         def handle_request_wrapper(request, actual_handler, *args, **kwargs)
# 
#             request_wrapper = TornadoRequestWrapper(request=request)
#             span = http_server.before_request(request=request_wrapper)
# 
#             with request_context.span_in_stack_context(span):
#                 return actual_handler(*args, **kwargs)
# 
#     :param span:
#     :return:
#         Return StackContext that wraps the request context.
#     """
# 
#     if not isinstance(opentracing.tracer.scope_manager, TornadoScopeManager):
#         raise RuntimeError('scope_manager is not TornadoScopeManager')
# 
#     # Enter the newly created stack context so we have
#     # storage available for Span activation.
#     context = tracer_stack_context()
#     entered_context = _TracerEnteredStackContext(context)
# 
#     if span is None:
#         return entered_context
# 
#     opentracing.tracer.scope_manager.activate(span, False)
#     assert opentracing.tracer.active_span is not None
#     assert opentracing.tracer.active_span is span
# 
#     return entered_context


# Path: tests/opentracing_instrumentation/test_thread_safe_request_context.py
import time
from threading import Thread
from tornado.stack_context import wrap
from opentracing_instrumentation.request_context import (
    get_current_span, span_in_stack_context,
)

# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.





def test__request_context_is_thread_safe(thread_safe_tracer):
    """
    Port of Uber's internal tornado-extras (by @sema).

    This test illustrates that the default Tornado's StackContext
    is not thread-safe. The test can be made to fail by commenting
    out these lines in the ThreadSafeStackContext constructor:

        if hasattr(self, 'contexts'):
            # only patch if context exists
            self.contexts = LocalContexts()
    """

    num_iterations = 1000
    num_workers = 10
    exception = [0]

    def async_task():
        time.sleep(0.001)

        assert get_current_span() is not None