示例#1
0
        public Task <T> RunCommandAsync <T>(object command, TimeSpan?timeout, CancellationToken cancellationToken)
        {
            Ensure.IsNotNull(command, "command");

            var commandDocument = command as BsonDocument;

            if (commandDocument == null)
            {
                if (command is string)
                {
                    commandDocument = BsonDocument.Parse((string)command);
                }
                else
                {
                    var commandSerializer = _settings.SerializerRegistry.GetSerializer(command.GetType());
                    commandDocument = new BsonDocumentWrapper(command, commandSerializer);
                }
            }

            var isReadCommand          = CanCommandBeSentToSecondary.Delegate(commandDocument);
            var serializer             = _settings.SerializerRegistry.GetSerializer <T>();
            var messageEncoderSettings = GetMessageEncoderSettings();

            if (isReadCommand)
            {
                var operation = new ReadCommandOperation <T>(_databaseNamespace, commandDocument, serializer, messageEncoderSettings);
                return(ExecuteReadOperation <T>(operation, timeout, cancellationToken));
            }
            else
            {
                var operation = new WriteCommandOperation <T>(_databaseNamespace, commandDocument, serializer, messageEncoderSettings);
                return(ExecuteWriteOperation <T>(operation, timeout, cancellationToken));
            }
        }
示例#2
0
        #pragma warning restore

        private TCommandResult RunCommandAs <TCommandResult>(
            IMongoCommand command,
            IBsonSerializer <TCommandResult> resultSerializer) where TCommandResult : CommandResult
        {
            var readerSettings = new BsonBinaryReaderSettings
            {
                Encoding           = _settings.ReadEncoding ?? MongoDefaults.ReadEncoding,
                GuidRepresentation = _settings.GuidRepresentation
            };
            var writerSettings = new BsonBinaryWriterSettings
            {
                Encoding           = _settings.WriteEncoding ?? MongoDefaults.WriteEncoding,
                GuidRepresentation = _settings.GuidRepresentation
            };
            var readPreference = _settings.ReadPreference;

            if (readPreference != ReadPreference.Primary)
            {
                if (_server.ProxyType == MongoServerProxyType.Unknown)
                {
                    _server.Connect();
                }
                if (_server.ProxyType == MongoServerProxyType.ReplicaSet && !CanCommandBeSentToSecondary.Delegate(command.ToBsonDocument()))
                {
                    readPreference = ReadPreference.Primary;
                }
            }
            var flags = (readPreference == ReadPreference.Primary) ? QueryFlags.None : QueryFlags.SlaveOk;

            var commandOperation = new CommandOperation <TCommandResult>(
                _name,
                readerSettings,
                writerSettings,
                command,
                flags,
                null, // options
                readPreference,
                resultSerializer);

            var connection = _server.AcquireConnection(readPreference);

            try
            {
                return(commandOperation.Execute(connection));
            }
            finally
            {
                _server.ReleaseConnection(connection);
            }
        }
        internal TCommandResult RunCommandAs <TCommandResult>(
            IMongoCommand command,
            IBsonSerializer <TCommandResult> resultSerializer,
            ReadPreference readPreference)
            where TCommandResult : CommandResult
        {
            var isReadCommand = CanCommandBeSentToSecondary.Delegate(command.ToBsonDocument());

            if (readPreference != ReadPreference.Primary)
            {
                var slidingTimeout = new SlidingTimeout(_server.Settings.ConnectTimeout);
                var cluster        = _server.Cluster;

                var clusterType = cluster.Description.Type;
                while (clusterType == ClusterType.Unknown)
                {
                    // TODO: find a way to block until the cluster description changes
                    slidingTimeout.ThrowIfExpired();
                    Thread.Sleep(TimeSpan.FromMilliseconds(20));
                    clusterType = cluster.Description.Type;
                }

                if (clusterType == ClusterType.ReplicaSet && !isReadCommand)
                {
                    readPreference = ReadPreference.Primary;
                }
            }

            TCommandResult      commandResult;
            var                 wrappedCommand = new BsonDocumentWrapper(command);
            MongoServerInstance serverInstance;

            if (isReadCommand)
            {
                commandResult = RunReadCommandAs <TCommandResult>(wrappedCommand, resultSerializer, readPreference, out serverInstance);
            }
            else
            {
                commandResult = RunWriteCommandAs <TCommandResult>(wrappedCommand, resultSerializer, out serverInstance);
            }

            commandResult.Command        = command.ToBsonDocument();
            commandResult.ServerInstance = serverInstance;

            return(commandResult);
        }
        internal TCommandResult RunCommandAs <TCommandResult>(
            IMongoCommand command,
            IBsonSerializer <TCommandResult> resultSerializer,
            ReadPreference readPreference)
            where TCommandResult : CommandResult
        {
            var commandDocument = command.ToBsonDocument();
            var isReadCommand   = CanCommandBeSentToSecondary.Delegate(commandDocument);

            if (readPreference != ReadPreference.Primary)
            {
                var timeoutAt = DateTime.UtcNow + _server.Settings.ConnectTimeout;
                var cluster   = _server.Cluster;

                var clusterType = cluster.Description.Type;
                while (clusterType == ClusterType.Unknown)
                {
                    // TODO: find a way to block until the cluster description changes
                    if (DateTime.UtcNow >= timeoutAt)
                    {
                        throw new TimeoutException();
                    }
                    Thread.Sleep(TimeSpan.FromMilliseconds(20));
                    clusterType = cluster.Description.Type;
                }

                if (clusterType == ClusterType.ReplicaSet && !isReadCommand)
                {
                    readPreference = ReadPreference.Primary;
                }
            }

            var messageEncoderSettings = GetMessageEncoderSettings();

            if (isReadCommand)
            {
                var operation = new ReadCommandOperation <TCommandResult>(_namespace, commandDocument, resultSerializer, messageEncoderSettings);
                return(ExecuteReadOperation(operation, readPreference));
            }
            else
            {
                var operation = new WriteCommandOperation <TCommandResult>(_namespace, commandDocument, resultSerializer, messageEncoderSettings);
                return(ExecuteWriteOperation(operation));
            }
        }
示例#5
0
        // constructors
        /// <summary>
        /// Initializes a new instance of the MongoCursorEnumerator class.
        /// </summary>
        /// <param name="cursor">The cursor to be enumerated.</param>
        public MongoCursorEnumerator(MongoCursor <TDocument> cursor)
        {
            _cursor         = cursor;
            _positiveLimit  = cursor.Limit >= 0 ? cursor.Limit : -cursor.Limit;
            _readPreference = _cursor.ReadPreference;
            _queryFlags     = _cursor.Flags;

            if (_readPreference.ReadPreferenceMode != ReadPreferenceMode.Primary && _cursor.Collection.Name == "$cmd")
            {
                if (cursor.Server.ProxyType == MongoServerProxyType.ReplicaSet && !CanCommandBeSentToSecondary.Delegate(_cursor.Query.ToBsonDocument()))
                {
                    // if the command can't be sent to a secondary, then we use primary here
                    // regardless of the user's choice.
                    _readPreference = ReadPreference.Primary;
                    // remove the slaveOk bit from the flags
                    _queryFlags &= ~QueryFlags.SlaveOk;
                }
            }
        }
        public Task <T> RunCommandAsync <T>(object command, CancellationToken cancellationToken)
        {
            Ensure.IsNotNull(command, "command");

            var commandDocument = BsonDocumentHelper.ToBsonDocument(_settings.SerializerRegistry, command);

            var isReadCommand          = CanCommandBeSentToSecondary.Delegate(commandDocument);
            var serializer             = _settings.SerializerRegistry.GetSerializer <T>();
            var messageEncoderSettings = GetMessageEncoderSettings();

            if (isReadCommand)
            {
                var operation = new ReadCommandOperation <T>(_databaseNamespace, commandDocument, serializer, messageEncoderSettings);
                return(ExecuteReadOperation <T>(operation, cancellationToken));
            }
            else
            {
                var operation = new WriteCommandOperation <T>(_databaseNamespace, commandDocument, serializer, messageEncoderSettings);
                return(ExecuteWriteOperation <T>(operation, cancellationToken));
            }
        }