ismaster.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. # Copyright 2014-2015 MongoDB, Inc.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. """Parse a response to the 'ismaster' command."""
  15. import itertools
  16. from bson.py3compat import imap
  17. from pymongo import common
  18. from pymongo.server_type import SERVER_TYPE
  19. def _get_server_type(doc):
  20. """Determine the server type from an ismaster response."""
  21. if not doc.get('ok'):
  22. return SERVER_TYPE.Unknown
  23. if doc.get('isreplicaset'):
  24. return SERVER_TYPE.RSGhost
  25. elif doc.get('setName'):
  26. if doc.get('hidden'):
  27. return SERVER_TYPE.RSOther
  28. elif doc.get('ismaster'):
  29. return SERVER_TYPE.RSPrimary
  30. elif doc.get('secondary'):
  31. return SERVER_TYPE.RSSecondary
  32. elif doc.get('arbiterOnly'):
  33. return SERVER_TYPE.RSArbiter
  34. else:
  35. return SERVER_TYPE.RSOther
  36. elif doc.get('msg') == 'isdbgrid':
  37. return SERVER_TYPE.Mongos
  38. else:
  39. return SERVER_TYPE.Standalone
  40. class IsMaster(object):
  41. __slots__ = ('_doc', '_server_type', '_is_writable', '_is_readable')
  42. def __init__(self, doc):
  43. """Parse an ismaster response from the server."""
  44. self._server_type = _get_server_type(doc)
  45. self._doc = doc
  46. self._is_writable = self._server_type in (
  47. SERVER_TYPE.RSPrimary,
  48. SERVER_TYPE.Standalone,
  49. SERVER_TYPE.Mongos)
  50. self._is_readable = (
  51. self.server_type == SERVER_TYPE.RSSecondary
  52. or self._is_writable)
  53. @property
  54. def server_type(self):
  55. return self._server_type
  56. @property
  57. def all_hosts(self):
  58. """List of hosts, passives, and arbiters known to this server."""
  59. return set(imap(common.clean_node, itertools.chain(
  60. self._doc.get('hosts', []),
  61. self._doc.get('passives', []),
  62. self._doc.get('arbiters', []))))
  63. @property
  64. def tags(self):
  65. """Replica set member tags or empty dict."""
  66. return self._doc.get('tags', {})
  67. @property
  68. def primary(self):
  69. """This server's opinion about who the primary is, or None."""
  70. if self._doc.get('primary'):
  71. return common.partition_node(self._doc['primary'])
  72. else:
  73. return None
  74. @property
  75. def replica_set_name(self):
  76. """Replica set name or None."""
  77. return self._doc.get('setName')
  78. @property
  79. def max_bson_size(self):
  80. return self._doc.get('maxBsonObjectSize', common.MAX_BSON_SIZE)
  81. @property
  82. def max_message_size(self):
  83. return self._doc.get('maxMessageSizeBytes', 2 * self.max_bson_size)
  84. @property
  85. def max_write_batch_size(self):
  86. return self._doc.get('maxWriteBatchSize', common.MAX_WRITE_BATCH_SIZE)
  87. @property
  88. def min_wire_version(self):
  89. return self._doc.get('minWireVersion', common.MIN_WIRE_VERSION)
  90. @property
  91. def max_wire_version(self):
  92. return self._doc.get('maxWireVersion', common.MAX_WIRE_VERSION)
  93. @property
  94. def election_id(self):
  95. return self._doc.get('electionId')
  96. @property
  97. def is_writable(self):
  98. return self._is_writable
  99. @property
  100. def is_readable(self):
  101. return self._is_readable