scope.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. # Copyright (c) 2017-2019 The OpenTracing Authors.
  2. #
  3. # Permission is hereby granted, free of charge, to any person obtaining a copy
  4. # of this software and associated documentation files (the "Software"), to deal
  5. # in the Software without restriction, including without limitation the rights
  6. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. # copies of the Software, and to permit persons to whom the Software is
  8. # furnished to do so, subject to the following conditions:
  9. #
  10. # The above copyright notice and this permission notice shall be included in
  11. # all copies or substantial portions of the Software.
  12. #
  13. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. # THE SOFTWARE.
  20. from __future__ import absolute_import
  21. from .span import Span
  22. class Scope(object):
  23. """A scope formalizes the activation and deactivation of a :class:`Span`,
  24. usually from a CPU standpoint. Many times a :class:`Span` will be extant
  25. (in that :meth:`Span.finish()` has not been called) despite being in a
  26. non-runnable state from a CPU/scheduler standpoint. For instance, a
  27. :class:`Span` representing the client side of an RPC will be unfinished but
  28. blocked on IO while the RPC is still outstanding. A scope defines when a
  29. given :class:`Span` is scheduled and on the path.
  30. :param manager: the :class:`ScopeManager` that created this :class:`Scope`.
  31. :type manager: ScopeManager
  32. :param span: the :class:`Span` used for this :class:`Scope`.
  33. :type span: Span
  34. """
  35. def __init__(self, manager, span):
  36. """Initializes a scope for *span*."""
  37. self._manager = manager
  38. self._span = span
  39. @property
  40. def span(self):
  41. """Returns the :class:`Span` wrapped by this :class:`Scope`.
  42. :rtype: Span
  43. """
  44. return self._span
  45. @property
  46. def manager(self):
  47. """Returns the :class:`ScopeManager` that created this :class:`Scope`.
  48. :rtype: ScopeManager
  49. """
  50. return self._manager
  51. def close(self):
  52. """Marks the end of the active period for this :class:`Scope`, updating
  53. :attr:`ScopeManager.active` in the process.
  54. NOTE: Calling this method more than once on a single :class:`Scope`
  55. leads to undefined behavior.
  56. """
  57. pass
  58. def __enter__(self):
  59. """Allows :class:`Scope` to be used inside a Python Context Manager."""
  60. return self
  61. def __exit__(self, exc_type, exc_val, exc_tb):
  62. """Calls :meth:`close()` when the execution is outside the Python
  63. Context Manager.
  64. If exception has occurred during execution, it is automatically logged
  65. and added as a tag to the :class:`Span`.
  66. :attr:`~operation.ext.tags.ERROR` will also be set to `True`.
  67. """
  68. Span._on_error(self.span, exc_type, exc_val, exc_tb)
  69. self.close()