Development of an internal social media platform with personalised dashboards for students
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.

abstract_channel.py 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. """Code common to Connection and Channel objects."""
  2. # Copyright (C) 2007-2008 Barry Pederson <bp@barryp.org>)
  3. #
  4. # This library is free software; you can redistribute it and/or
  5. # modify it under the terms of the GNU Lesser General Public
  6. # License as published by the Free Software Foundation; either
  7. # version 2.1 of the License, or (at your option) any later version.
  8. #
  9. # This library is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. # Lesser General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU Lesser General Public
  15. # License along with this library; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
  17. from __future__ import absolute_import
  18. from .exceptions import AMQPNotImplementedError, RecoverableConnectionError
  19. from .serialization import AMQPWriter
  20. __all__ = ['AbstractChannel']
  21. class AbstractChannel(object):
  22. """Superclass for both the Connection, which is treated
  23. as channel 0, and other user-created Channel objects.
  24. The subclasses must have a _METHOD_MAP class property, mapping
  25. between AMQP method signatures and Python methods.
  26. """
  27. def __init__(self, connection, channel_id):
  28. self.connection = connection
  29. self.channel_id = channel_id
  30. connection.channels[channel_id] = self
  31. self.method_queue = [] # Higher level queue for methods
  32. self.auto_decode = False
  33. def __enter__(self):
  34. return self
  35. def __exit__(self, *exc_info):
  36. self.close()
  37. def _send_method(self, method_sig, args=bytes(), content=None):
  38. """Send a method for our channel."""
  39. conn = self.connection
  40. if conn is None:
  41. raise RecoverableConnectionError('connection already closed')
  42. if isinstance(args, AMQPWriter):
  43. args = args.getvalue()
  44. conn.method_writer.write_method(
  45. self.channel_id, method_sig, args, content,
  46. )
  47. def close(self):
  48. """Close this Channel or Connection"""
  49. raise NotImplementedError('Must be overriden in subclass')
  50. def wait(self, allowed_methods=None, timeout=None):
  51. """Wait for a method that matches our allowed_methods parameter (the
  52. default value of None means match any method), and dispatch to it."""
  53. method_sig, args, content = self.connection._wait_method(
  54. self.channel_id, allowed_methods, timeout)
  55. return self.dispatch_method(method_sig, args, content)
  56. def dispatch_method(self, method_sig, args, content):
  57. if content and \
  58. self.auto_decode and \
  59. hasattr(content, 'content_encoding'):
  60. try:
  61. content.body = content.body.decode(content.content_encoding)
  62. except Exception:
  63. pass
  64. try:
  65. amqp_method = self._METHOD_MAP[method_sig]
  66. except KeyError:
  67. raise AMQPNotImplementedError(
  68. 'Unknown AMQP method {0!r}'.format(method_sig))
  69. if content is None:
  70. return amqp_method(self, args)
  71. else:
  72. return amqp_method(self, args, content)
  73. #: Placeholder, the concrete implementations will have to
  74. #: supply their own versions of _METHOD_MAP
  75. _METHOD_MAP = {}