diff --git a/pymongo/ismaster.py b/pymongo/ismaster.py index 145bbd151..334f9de16 100644 --- a/pymongo/ismaster.py +++ b/pymongo/ismaster.py @@ -122,3 +122,9 @@ class IsMaster(object): @property def is_readable(self): return self._is_readable + + @property + def me(self): + me = self._doc.get('me') + if me: + return common.clean_node(me) diff --git a/pymongo/server_description.py b/pymongo/server_description.py index 1763e2e53..816be88b5 100644 --- a/pymongo/server_description.py +++ b/pymongo/server_description.py @@ -32,7 +32,7 @@ class ServerDescription(object): '_address', '_server_type', '_all_hosts', '_tags', '_replica_set_name', '_primary', '_max_bson_size', '_max_message_size', '_max_write_batch_size', '_min_wire_version', '_max_wire_version', - '_round_trip_time', '_is_writable', '_is_readable', '_error', + '_round_trip_time', '_me', '_is_writable', '_is_readable', '_error', '_election_id') def __init__( @@ -59,6 +59,7 @@ class ServerDescription(object): self._is_writable = ismaster.is_writable self._is_readable = ismaster.is_readable self._round_trip_time = round_trip_time + self._me = ismaster.me self._error = error @property @@ -112,6 +113,10 @@ class ServerDescription(object): def election_id(self): return self._election_id + @property + def me(self): + return self._me + @property def round_trip_time(self): """The current average latency or None.""" diff --git a/pymongo/topology_description.py b/pymongo/topology_description.py index 3e0dd2c71..efb9b750b 100644 --- a/pymongo/topology_description.py +++ b/pymongo/topology_description.py @@ -300,6 +300,9 @@ def _update_rs_with_primary_from_member( if replica_set_name != server_description.replica_set_name: sds.pop(server_description.address) + elif (server_description.me and + server_description.address != server_description.me): + sds.pop(server_description.address) # Had this member been the primary? return _check_has_primary(sds) @@ -330,6 +333,10 @@ def _update_rs_no_primary_from_member( if address not in sds: sds[address] = ServerDescription(address) + if (server_description.me and + server_description.address != server_description.me): + sds.pop(server_description.address) + return topology_type, replica_set_name diff --git a/test/discovery_and_monitoring/rs/primary_mismatched_me.json b/test/discovery_and_monitoring/rs/primary_mismatched_me.json new file mode 100644 index 000000000..fd9eb9831 --- /dev/null +++ b/test/discovery_and_monitoring/rs/primary_mismatched_me.json @@ -0,0 +1,37 @@ +{ + "description": "Primary mismatched me", + "phases": [ + { + "outcome": { + "servers": { + "a:27017": { + "setName": null, + "type": "Unknown" + }, + "b:27017": { + "setName": null, + "type": "Unknown" + } + }, + "setName": "rs", + "topologyType": "ReplicaSetNoPrimary" + }, + "responses": [ + [ + "localhost:27017", + { + "hosts": [ + "a:27017", + "b:27017" + ], + "ismaster": true, + "me": "a:27017", + "ok": 1, + "setName": "rs" + } + ] + ] + } + ], + "uri": "mongodb://localhost:27017/?replicaSet=rs" +} diff --git a/test/discovery_and_monitoring/rs/primary_to_no_primary_mismatched_me.json b/test/discovery_and_monitoring/rs/primary_to_no_primary_mismatched_me.json new file mode 100644 index 000000000..a940701f8 --- /dev/null +++ b/test/discovery_and_monitoring/rs/primary_to_no_primary_mismatched_me.json @@ -0,0 +1,68 @@ +{ + "description": "Primary to no primary with mismatched me", + "phases": [ + { + "outcome": { + "servers": { + "a:27017": { + "setName": "rs", + "type": "RSPrimary" + }, + "b:27017": { + "setName": null, + "type": "Unknown" + } + }, + "setName": "rs", + "topologyType": "ReplicaSetWithPrimary" + }, + "responses": [ + [ + "a:27017", + { + "hosts": [ + "a:27017", + "b:27017" + ], + "ismaster": true, + "me": "a:27017", + "ok": 1, + "setName": "rs" + } + ] + ] + }, + { + "outcome": { + "servers": { + "c:27017": { + "setName": null, + "type": "Unknown" + }, + "d:27017": { + "setName": null, + "type": "Unknown" + } + }, + "setName": "rs", + "topologyType": "ReplicaSetNoPrimary" + }, + "responses": [ + [ + "a:27017", + { + "hosts": [ + "c:27017", + "d:27017" + ], + "ismaster": true, + "me": "c:27017", + "ok": 1, + "setName": "rs" + } + ] + ] + } + ], + "uri": "mongodb://a/?replicaSet=rs" +} diff --git a/test/discovery_and_monitoring/rs/rsother_discovered.json b/test/discovery_and_monitoring/rs/rsother_discovered.json index 994b1929d..a4a8949cc 100644 --- a/test/discovery_and_monitoring/rs/rsother_discovered.json +++ b/test/discovery_and_monitoring/rs/rsother_discovered.json @@ -1,37 +1,59 @@ { - "description": "RSOther discovered", + "description": "RSOther discovered", "phases": [ { "outcome": { "servers": { "a:27017": { - "setName": null, - "type": "Unknown" - }, - "b:27017": { - "setName": "rs", + "setName": "rs", "type": "RSOther" + }, + "b:27017": { + "setName": "rs", + "type": "RSOther" + }, + "c:27017": { + "setName": null, + "type": "Unknown" + }, + "d:27017": { + "setName": null, + "type": "Unknown" } - }, - "setName": "rs", + }, + "setName": "rs", "topologyType": "ReplicaSetNoPrimary" - }, + }, "responses": [ [ - "b:27017", + "a:27017", + { + "hidden": true, + "hosts": [ + "c:27017", + "d:27017" + ], + "ismaster": false, + "ok": 1, + "secondary": true, + "setName": "rs" + } + ], + [ + "b:27017", { "hosts": [ - "a:27017", - "b:27017" - ], - "ismaster": false, - "ok": 1, - "secondary": false, + "c:27017", + "d:27017" + ], + "ismaster": false, + "ok": 1, + "secondary": false, "setName": "rs" } ] ] } - ], + ], "uri": "mongodb://a,b/?replicaSet=rs" } diff --git a/test/discovery_and_monitoring/rs/secondary_mismatched_me.json b/test/discovery_and_monitoring/rs/secondary_mismatched_me.json new file mode 100644 index 000000000..60059a7f7 --- /dev/null +++ b/test/discovery_and_monitoring/rs/secondary_mismatched_me.json @@ -0,0 +1,37 @@ +{ + "description": "Secondary mismatched me", + "phases": [ + { + "outcome": { + "servers": { + "a:27017": { + "setName": null, + "type": "Unknown" + }, + "b:27017": { + "setName": null, + "type": "Unknown" + } + }, + "setName": "rs", + "topologyType": "ReplicaSetNoPrimary" + }, + "responses": [ + [ + "localhost:27017", + { + "me": "a:27017", + "hosts": [ + "a:27017", + "b:27017" + ], + "ismaster": false, + "ok": 1, + "setName": "rs" + } + ] + ] + } + ], + "uri": "mongodb://localhost:27017/?replicaSet=rs" +}