You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

interfaces.py 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. ###############################################################################
  2. #
  3. # The MIT License (MIT)
  4. #
  5. # Copyright (c) Crossbar.io Technologies GmbH
  6. #
  7. # Permission is hereby granted, free of charge, to any person obtaining a copy
  8. # of this software and associated documentation files (the "Software"), to deal
  9. # in the Software without restriction, including without limitation the rights
  10. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. # copies of the Software, and to permit persons to whom the Software is
  12. # furnished to do so, subject to the following conditions:
  13. #
  14. # The above copyright notice and this permission notice shall be included in
  15. # all copies or substantial portions of the Software.
  16. #
  17. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. # THE SOFTWARE.
  24. #
  25. ###############################################################################
  26. from __future__ import absolute_import
  27. import abc
  28. import six
  29. #: all the log-levels that txaio recognizes
  30. log_levels = [
  31. 'none',
  32. 'critical',
  33. 'error',
  34. 'warn',
  35. 'info',
  36. 'debug',
  37. 'trace',
  38. ]
  39. @six.add_metaclass(abc.ABCMeta)
  40. class IBatchedTimer(object):
  41. """
  42. Objects created by :met:`txaio.make_batched_timer` implement this
  43. interface.
  44. These APIs allow you to put call_later()'s into "buckets",
  45. reducing the number of actual underlying delayed calls that the
  46. event-loop (asyncio or Twisted) needs to deal with. Obviously, you
  47. lose some amount of precision in when the timers fire in exchange
  48. for less memory use, and fewer objects on the queues for the
  49. underlying event-loop/reactor.
  50. As a concrete example, in Autobahn we're using this to batch
  51. together timers for the "auto ping" feature. In this case, it is
  52. not vital when precisely the timers fire, but as the
  53. connection-count increases the number of outstanding timers
  54. becomes quite large.
  55. It is intended to be used like so:
  56. class Something(object):
  57. timers = txaio.make_batched_timer()
  58. def a_method(self):
  59. self.timers.call_later() # drop-in API from txaio.call_later
  60. """
  61. def call_later(self, delay, func, *args, **kw):
  62. """
  63. This speaks the same API as :meth:`txaio.call_later` and also
  64. returns an object that has a ``.cancel`` method.
  65. You cannot rely on any other methods/attributes of the
  66. returned object. The timeout will actually fire at an
  67. aribtrary time "close" to the delay specified, depening upon
  68. the arguments this IBatchedTimer was created with.
  69. """
  70. @six.add_metaclass(abc.ABCMeta)
  71. class ILogger(object):
  72. """
  73. This defines the methods you can call on the object returned from
  74. :meth:`txaio.make_logger` -- although the actual object may have
  75. additional methods, you should *only* call the methods listed
  76. here.
  77. All the log methods have the same signature, they just differ in
  78. what "log level" they represent to the handlers/emitters. The
  79. ``message`` argument is a format string using `PEP3101
  80. <https://www.python.org/dev/peps/pep-3101/>`_-style references to
  81. things from the ``kwargs``. Note that there are also the following
  82. keys added to the ``kwargs``: ``log_time`` and ``log_level``.
  83. For example::
  84. class MyThing(object):
  85. log = txaio.make_logger()
  86. def something_interesting(self, things=dict(one=1, two=2)):
  87. try:
  88. self.log.debug("Called with {things[one]}", things=things)
  89. result = self._method_call()
  90. self.log.info("Got '{result}'.", result=result)
  91. except Exception:
  92. fail = txaio.create_failure()
  93. self.log.critical(txaio.failure_format_traceback(fail))
  94. The philsophy behind txaio's interface is fairly similar to
  95. Twisted's logging APIs after version 15. See `Twisted's
  96. documentation
  97. <http://twistedmatrix.com/documents/current/core/howto/logger.html>`_
  98. for details.
  99. """
  100. # stdlib notes:
  101. # levels:
  102. # CRITICAL 50
  103. # ERROR 40
  104. # WARNING 30
  105. # INFO 20
  106. # DEBUG 10
  107. # NOTSET 0
  108. # NOTES
  109. # things in Twisted's event:
  110. # - log_level
  111. # - log_failure (sometimes?)
  112. # - log_format (can be None)
  113. # - log_source (sometimes? no, always, but sometimes None)
  114. # - log_namespace
  115. #
  116. # .warn not warning!
  117. def critical(self, message, **kwargs):
  118. "log a critical-level message"
  119. def error(self, message, **kwargs):
  120. "log a error-level message"
  121. def warn(self, message, **kwargs):
  122. "log a error-level message"
  123. def info(self, message, **kwargs):
  124. "log an info-level message"
  125. def debug(self, message, **kwargs):
  126. "log an debug-level message"
  127. def trace(self, message, **kwargs):
  128. "log a trace-level message"
  129. @six.add_metaclass(abc.ABCMeta)
  130. class IFailedFuture(object):
  131. """
  132. This defines the interface for a common object encapsulating a
  133. failure from either an asyncio task/coroutine or a Twisted
  134. Deferred.
  135. An instance implementing this interface is given to any
  136. ``errback`` callables you provide via :meth:`txaio.add_callbacks`
  137. In your errback you can extract information from an IFailedFuture
  138. with :meth:`txaio.failure_message` and
  139. :meth:`txaio.failure_traceback` or use ``.value`` to get the
  140. Exception instance.
  141. Depending on other details or methods will probably cause
  142. incompatibilities between asyncio and Twisted.
  143. """
  144. @abc.abstractproperty
  145. def value(self):
  146. """
  147. An actual Exception instance. Same as the second item returned from
  148. ``sys.exc_info()``
  149. """