diff --git a/Driver/Core/MongoCursorEnumerator.cs b/Driver/Core/MongoCursorEnumerator.cs index 23c4d58469b..672207b4bd4 100644 --- a/Driver/Core/MongoCursorEnumerator.cs +++ b/Driver/Core/MongoCursorEnumerator.cs @@ -330,14 +330,45 @@ private void KillCursor() private IMongoQuery WrapQuery() { - if (_cursor.Options == null) + BsonDocument formattedReadPreference = null; + if (_serverInstance.InstanceType == MongoServerInstanceType.ShardRouter) + { + var readPreference = _cursor.ReadPreference; + + BsonArray tagSetsArray = null; + if (readPreference.ReadPreferenceMode != ReadPreferenceMode.Primary && readPreference.TagSets != null) + { + tagSetsArray = new BsonArray(); + foreach (var tagSet in readPreference.TagSets) + { + var tagSetDocument = new BsonDocument(); + foreach (var tag in tagSet) + { + tagSetDocument.Add(tag.Name, tag.Value); + } + tagSetsArray.Add(tagSetDocument); + } + } + + formattedReadPreference = new BsonDocument + { + { "mode", MongoUtils.ToCamelCase(readPreference.ReadPreferenceMode.ToString()) }, + { "tags", tagSetsArray, tagSetsArray != null } // optional + }; + } + + if (_cursor.Options == null && formattedReadPreference == null) { return _cursor.Query; } else { var query = (_cursor.Query == null) ? (BsonValue)new BsonDocument() : BsonDocumentWrapper.Create(_cursor.Query); - var wrappedQuery = new QueryDocument("$query", query); + var wrappedQuery = new QueryDocument + { + { "$readPreference", formattedReadPreference, formattedReadPreference != null }, // only if sending query to a mongos + { "$query", query } + }; wrappedQuery.Merge(_cursor.Options); return wrappedQuery; } diff --git a/Driver/Core/MongoServerInstance.cs b/Driver/Core/MongoServerInstance.cs index f5f8c803b16..005436dc531 100755 --- a/Driver/Core/MongoServerInstance.cs +++ b/Driver/Core/MongoServerInstance.cs @@ -83,7 +83,7 @@ public sealed class MongoServerInstance private ReplicaSetInformation _replicaSetInformation; private int _sequentialId; private MongoServerState _state; - private MongoServerInstanceType _type; + private MongoServerInstanceType _instanceType; // constructors /// @@ -99,7 +99,7 @@ internal MongoServerInstance(MongoServer server, MongoServerAddress address) _maxDocumentSize = MongoDefaults.MaxDocumentSize; _maxMessageLength = MongoDefaults.MaxMessageLength; _state = MongoServerState.Disconnected; - _type = MongoServerInstanceType.Unknown; + _instanceType = MongoServerInstanceType.Unknown; _connectionPool = new MongoConnectionPool(this); _pingTimeAggregator = new PingTimeAggregator(5); _stateVerificationTimer = new Timer(o => StateVerificationTimerCallback(), null, TimeSpan.Zero, TimeSpan.FromSeconds(10)); @@ -127,15 +127,15 @@ internal ReplicaSetInformation ReplicaSetInformation } /// - /// Gets the type. + /// Gets the instance type. /// - internal MongoServerInstanceType Type + internal MongoServerInstanceType InstanceType { get { lock (_serverInstanceLock) { - return _type; + return _instanceType; } } } @@ -508,7 +508,7 @@ internal void SetState(MongoServerState state) { lock(_serverInstanceLock) { - SetState(state, _type, _isPrimary, _isSecondary, _isPassive, _isArbiter, _replicaSetInformation); + SetState(state, _instanceType, _isPrimary, _isSecondary, _isPassive, _isArbiter, _replicaSetInformation); } } @@ -546,17 +546,17 @@ private void LookupServerInformation(MongoConnection connection) } ReplicaSetInformation replicaSetInformation = null; - MongoServerInstanceType type = MongoServerInstanceType.StandAlone; + MongoServerInstanceType instanceType = MongoServerInstanceType.StandAlone; if (isMasterResult.ReplicaSetName != null) { var tagSet = new ReplicaSetTagSet(); var peers = isMasterResult.Hosts.Concat(isMasterResult.Passives).Concat(isMasterResult.Arbiters).ToList(); replicaSetInformation = new ReplicaSetInformation(isMasterResult.ReplicaSetName, isMasterResult.Primary, peers, tagSet); - type = MongoServerInstanceType.ReplicaSetMember; + instanceType = MongoServerInstanceType.ReplicaSetMember; } else if (isMasterResult.Message != null && isMasterResult.Message == "isdbgrid") { - type = MongoServerInstanceType.ShardRouter; + instanceType = MongoServerInstanceType.ShardRouter; } lock (_serverInstanceLock) @@ -566,7 +566,7 @@ private void LookupServerInformation(MongoConnection connection) _maxMessageLength = isMasterResult.MaxMessageLength; _buildInfo = buildInfo; this.SetState(MongoServerState.Connected, - type, + instanceType, isMasterResult.IsPrimary, isMasterResult.IsSecondary, isMasterResult.IsPassive, @@ -585,7 +585,7 @@ private void LookupServerInformation(MongoConnection connection) _maxDocumentSize = MongoDefaults.MaxDocumentSize; _maxMessageLength = MongoDefaults.MaxMessageLength; _buildInfo = null; - this.SetState(MongoServerState.Disconnected, _type, false, false, false, false, null); + this.SetState(MongoServerState.Disconnected, _instanceType, false, false, false, false, null); } } } @@ -663,7 +663,7 @@ internal void StateVerificationTimerCallback() private void SetState( MongoServerState state, - MongoServerInstanceType type, + MongoServerInstanceType instanceType, bool isPrimary, bool isSecondary, bool isPassive, @@ -678,11 +678,11 @@ internal void StateVerificationTimerCallback() { replicaSetInformationIsDifferent = true; } - if (_state != state || _type != type || replicaSetInformationIsDifferent || _isPrimary != isPrimary || _isSecondary != isSecondary || _isPassive != isPassive || _isArbiter != isArbiter) + if (_state != state || _instanceType != instanceType || replicaSetInformationIsDifferent || _isPrimary != isPrimary || _isSecondary != isSecondary || _isPassive != isPassive || _isArbiter != isArbiter) { changed = true; _state = state; - _type = type; + _instanceType = instanceType; if (_replicaSetInformation != replicaSetInformation) { _replicaSetInformation = replicaSetInformation; diff --git a/Driver/Core/ReadPreference.cs b/Driver/Core/ReadPreference.cs index df83111daea..d12713daee6 100644 --- a/Driver/Core/ReadPreference.cs +++ b/Driver/Core/ReadPreference.cs @@ -354,7 +354,7 @@ public bool MatchesInstance(MongoServerInstance instance) throw new MongoInternalException("Invalid ReadPreferenceMode"); } - if (_tagSets != null && instance.Type == MongoServerInstanceType.ReplicaSetMember) + if (_tagSets != null && instance.InstanceType == MongoServerInstanceType.ReplicaSetMember) { var someSetMatches = false; foreach (var tagSet in _tagSets) @@ -387,7 +387,8 @@ public override string ToString() } else { - return string.Format("{0}(tags: {1})}", _readPreferenceMode, _tagSets); + var tagSets = string.Format("[{0}]", string.Join(", ", _tagSets.Select(ts => ts.ToString()).ToArray())); + return string.Format("{0} (tags = {1})", _readPreferenceMode, tagSets); } } diff --git a/Driver/Core/ReplicaSetTag.cs b/Driver/Core/ReplicaSetTag.cs index 5073fe56962..468c059ecf3 100644 --- a/Driver/Core/ReplicaSetTag.cs +++ b/Driver/Core/ReplicaSetTag.cs @@ -134,7 +134,7 @@ public override int GetHashCode() /// A string representation of the user. public override string ToString() { - return string.Format("{0}={1}", _name, _value); + return string.Format("{0}:{1}", _name, _value); } // private methods diff --git a/Driver/Core/ReplicaSetTagSet.cs b/Driver/Core/ReplicaSetTagSet.cs index a2162bb6123..de25e419f61 100644 --- a/Driver/Core/ReplicaSetTagSet.cs +++ b/Driver/Core/ReplicaSetTagSet.cs @@ -223,7 +223,7 @@ public bool IsFrozen public bool MatchesInstance(MongoServerInstance instance) { // an empty tag set matches anything - if (instance.Type != MongoServerInstanceType.ReplicaSetMember || _tags.Count == 0) + if (instance.InstanceType != MongoServerInstanceType.ReplicaSetMember || _tags.Count == 0) { return true; } @@ -246,7 +246,7 @@ public bool MatchesInstance(MongoServerInstance instance) /// A string representation of the user. public override string ToString() { - return string.Join(", ", _tags.Select(t => t.ToString()).ToArray()); + return string.Format("{{{0}}}", string.Join(", ", _tags.Select(t => t.ToString()).ToArray())); } // private methods diff --git a/Driver/Internal/DirectMongoServerProxy.cs b/Driver/Internal/DirectMongoServerProxy.cs index 0cf94775a24..7ef742885aa 100644 --- a/Driver/Internal/DirectMongoServerProxy.cs +++ b/Driver/Internal/DirectMongoServerProxy.cs @@ -160,7 +160,7 @@ public void Connect(TimeSpan timeout, ReadPreference readPreference) } if (_server.Settings.ReplicaSetName != null && - (_instance.Type != MongoServerInstanceType.ReplicaSetMember || _instance.ReplicaSetInformation.Name != _server.Settings.ReplicaSetName)) + (_instance.InstanceType != MongoServerInstanceType.ReplicaSetMember || _instance.ReplicaSetInformation.Name != _server.Settings.ReplicaSetName)) { exceptions.Add(new MongoConnectionException(string.Format("The server '{0}' is not a member of replica set '{1}'.", address, _server.Settings.ReplicaSetName))); continue; diff --git a/Driver/Internal/DiscoveringMongoServerProxy.cs b/Driver/Internal/DiscoveringMongoServerProxy.cs index 185451b1a2a..47e49c1ab0b 100644 --- a/Driver/Internal/DiscoveringMongoServerProxy.cs +++ b/Driver/Internal/DiscoveringMongoServerProxy.cs @@ -308,15 +308,15 @@ private void Discover(TimeSpan timeout) private void CreateActualProxy(MongoServerInstance instance, BlockingQueue connectionQueue) { // we are already in a write lock here... - if (instance.Type == MongoServerInstanceType.ReplicaSetMember) + if (instance.InstanceType == MongoServerInstanceType.ReplicaSetMember) { _serverProxy = new ReplicaSetMongoServerProxy(_server, _instances, connectionQueue, _connectionAttempt); } - else if (instance.Type == MongoServerInstanceType.ShardRouter) + else if (instance.InstanceType == MongoServerInstanceType.ShardRouter) { _serverProxy = new ShardedMongoServerProxy(_server, _instances, connectionQueue, _connectionAttempt); } - else if (instance.Type == MongoServerInstanceType.StandAlone) + else if (instance.InstanceType == MongoServerInstanceType.StandAlone) { var otherInstances = _instances.Where(x => x != instance).ToList(); foreach (var otherInstance in otherInstances) diff --git a/Driver/Internal/ReplicaSetMongoServerProxy.cs b/Driver/Internal/ReplicaSetMongoServerProxy.cs index c7fea1944bf..558536d0c31 100644 --- a/Driver/Internal/ReplicaSetMongoServerProxy.cs +++ b/Driver/Internal/ReplicaSetMongoServerProxy.cs @@ -133,7 +133,7 @@ protected override MongoServerState DetermineServerState(MongoServerState curren /// protected override bool IsValidInstance(MongoServerInstance instance) { - if (instance.Type != MongoServerInstanceType.ReplicaSetMember) + if (instance.InstanceType != MongoServerInstanceType.ReplicaSetMember) { return false; } diff --git a/Driver/Internal/ShardedMongoServerProxy.cs b/Driver/Internal/ShardedMongoServerProxy.cs index c2d17c577d4..13275601acb 100644 --- a/Driver/Internal/ShardedMongoServerProxy.cs +++ b/Driver/Internal/ShardedMongoServerProxy.cs @@ -114,7 +114,7 @@ protected override MongoServerState DetermineServerState(MongoServerState curren /// protected override bool IsValidInstance(MongoServerInstance instance) { - return instance.Type == MongoServerInstanceType.ShardRouter; + return instance.InstanceType == MongoServerInstanceType.ShardRouter; } } } \ No newline at end of file