示例#1
0
        /// <summary>
        /// Kills the cursor.
        /// </summary>
        private void KillCursor(long cursorId)
        {
            var killCursorsMessage = new KillCursorsMessage(cursorId);

            try {
                _connection.SendMessage(killCursorsMessage, _databaseName);
                Id = 0;
            } catch (IOException exception) {
                throw new MongoConnectionException("Could not read data, communication failure", _connection, exception);
            }
        }
示例#2
0
        // static constructor
        static KillCursorsMessageJsonEncoderTests()
        {
            __testMessage = new KillCursorsMessage(__requestId, __cursorIds);

            __testMessageJson =
                "{ " +
                "\"opcode\" : \"killCursors\", " +
                "\"requestId\" : 1, " +
                "\"cursorIds\" : [NumberLong(2)]" +
                " }";
        }
示例#3
0
        public void Dispose()
        {
            if (this.Id == 0)
            {
                return;              //All server side resources disposed of.
            }
            KillCursorsMessage kcm = new KillCursorsMessage(this.Id);

            try{
                this.id = 0;
                connection.SendMessage(kcm);
            }catch (IOException ioe) {
                throw new MongoCommException("Could not read data, communication failure", this.connection, ioe);
            }
        }
        /// <summary>
        /// Writes the message.
        /// </summary>
        /// <param name="message">The message.</param>
        public void WriteMessage(KillCursorsMessage message)
        {
            Ensure.IsNotNull(message, "message");

            var messageDocument = new BsonDocument
            {
                { "opcode", "killCursors" },
                { "requestId", message.RequestId },
                { "cursorIds", new BsonArray(message.CursorIds.Select(id => new BsonInt64(id))) }
            };

            var jsonWriter = CreateJsonWriter();
            var messageContext = BsonSerializationContext.CreateRoot(jsonWriter);
            BsonDocumentSerializer.Instance.Serialize(messageContext, messageDocument);
        }
示例#5
0
        /// <summary>
        /// Writes the message.
        /// </summary>
        /// <param name="message">The message.</param>
        public void WriteMessage(KillCursorsMessage message)
        {
            Ensure.IsNotNull(message, nameof(message));

            var messageDocument = new BsonDocument
            {
                { "opcode", "killCursors" },
                { "requestId", message.RequestId },
                { "cursorIds", new BsonArray(message.CursorIds.Select(id => new BsonInt64(id))) }
            };

            var jsonWriter     = CreateJsonWriter();
            var messageContext = BsonSerializationContext.CreateRoot(jsonWriter);

            BsonDocumentSerializer.Instance.Serialize(messageContext, messageDocument);
        }
        // static constructor
        static KillCursorsMessageBinaryEncoderTests()
        {
            __testMessage = new KillCursorsMessage(__requestId, __cursorIds);

            __testMessageBytes = new byte[]
            {
                0, 0, 0, 0,            // messageLength
                1, 0, 0, 0,            // requestId
                0, 0, 0, 0,            // responseTo
                215, 7, 0, 0,          // opcode = 2007
                0, 0, 0, 0,            // reserved
                1, 0, 0, 0,            // numberOfCursorIds
                2, 0, 0, 0, 0, 0, 0, 0 // cursorIds[0]
            };
            __testMessageBytes[0] = (byte)__testMessageBytes.Length;
        }
示例#7
0
        public async Task SendMessageAsync_should_throw_MongoConnectionClosedException_for_waiting_tasks()
        {
            using (var stream = Substitute.For <Stream>())
            {
                _streamFactory.CreateStreamAsync(null, CancellationToken.None)
                .ReturnsForAnyArgs(Task.FromResult <Stream>(stream));

                var readTcs = new TaskCompletionSource <int>();
                stream.ReadAsync(null, 0, 0, CancellationToken.None)
                .ReturnsForAnyArgs(readTcs.Task);

                var writeTcs = new TaskCompletionSource <int>();
                stream.WriteAsync(null, 0, 0, CancellationToken.None)
                .ReturnsForAnyArgs(writeTcs.Task);

                await _subject.OpenAsync(CancellationToken.None);

                _capturedEvents.Clear();

                var message1 = new KillCursorsMessage(1, new[] { 1L });
                var task1    = _subject.SendMessageAsync(message1, _messageEncoderSettings, CancellationToken.None);

                var message2 = new KillCursorsMessage(2, new[] { 2L });
                var task2    = _subject.SendMessageAsync(message2, _messageEncoderSettings, CancellationToken.None);

                writeTcs.SetException(new SocketException());

                Func <Task> act1 = () => task1;
                act1.ShouldThrow <MongoConnectionException>()
                .WithInnerException <SocketException>()
                .And.ConnectionId.Should().Be(_subject.ConnectionId);

                Func <Task> act2 = () => task2;
                act2.ShouldThrow <MongoConnectionClosedException>();

                _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesEvent>();
                _capturedEvents.Next().Should().BeOfType <CommandStartedEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesEvent>();
                _capturedEvents.Next().Should().BeOfType <CommandStartedEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionFailedEvent>();
                _capturedEvents.Next().Should().BeOfType <CommandFailedEvent>();
                _capturedEvents.Next().Should().BeOfType <CommandFailedEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesFailedEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesFailedEvent>();
                _capturedEvents.Any().Should().BeFalse();
            }
        }
示例#8
0
        /// <summary>
        /// Writes the message.
        /// </summary>
        /// <param name="message">The message.</param>
        public void WriteMessage(KillCursorsMessage message)
        {
            Ensure.IsNotNull(message, "message");

            var binaryWriter  = CreateBinaryWriter();
            var stream        = binaryWriter.BsonStream;
            var startPosition = stream.Position;

            stream.WriteInt32(0); // messageSize
            stream.WriteInt32(message.RequestId);
            stream.WriteInt32(0); // responseTo
            stream.WriteInt32((int)Opcode.KillCursors);
            stream.WriteInt32(0); // reserved
            stream.WriteInt32(message.CursorIds.Count);
            foreach (var cursorId in message.CursorIds)
            {
                stream.WriteInt64(cursorId);
            }
            stream.BackpatchSize(startPosition);
        }
        /// <summary>
        /// Writes the message.
        /// </summary>
        /// <param name="message">The message.</param>
        public void WriteMessage(KillCursorsMessage message)
        {
            Ensure.IsNotNull(message, nameof(message));

            var binaryWriter = CreateBinaryWriter();
            var stream = binaryWriter.BsonStream;
            var startPosition = stream.Position;

            stream.WriteInt32(0); // messageSize
            stream.WriteInt32(message.RequestId);
            stream.WriteInt32(0); // responseTo
            stream.WriteInt32((int)Opcode.KillCursors);
            stream.WriteInt32(0); // reserved
            stream.WriteInt32(message.CursorIds.Count);
            foreach (var cursorId in message.CursorIds)
            {
                stream.WriteInt64(cursorId);
            }
            stream.BackpatchSize(startPosition);
        }
        private void ProcessKillCursorsMessages(KillCursorsMessage originalMessage, ConnectionId connectionId, Stopwatch stopwatch)
        {
            const string commandName = "killCursors";
            var          operationId = EventContext.OperationId;

            if (_startedEvent != null)
            {
                var collectionNamespace = EventContext.KillCursorsCollectionNamespace ?? DatabaseNamespace.Admin.CommandCollection;
                var command             = new BsonDocument
                {
                    { commandName, collectionNamespace.CollectionName },
                    { "cursors", new BsonArray(originalMessage.CursorIds) }
                };

                var @event = new CommandStartedEvent(
                    commandName,
                    command,
                    collectionNamespace.DatabaseNamespace,
                    operationId,
                    originalMessage.RequestId,
                    connectionId);

                _startedEvent(@event);
            }

            if (_shouldTrackState)
            {
                _state.TryAdd(originalMessage.RequestId, new CommandState
                {
                    CommandName          = commandName,
                    OperationId          = operationId,
                    Stopwatch            = stopwatch,
                    ExpectedResponseType = ExpectedResponseType.None,
                    NoResponseResponse   = new BsonDocument
                    {
                        { "ok", 1 },
                        { "cursorsUnknown", new BsonArray(originalMessage.CursorIds) }
                    }
                });
            }
        }
        public void SendMessageAsync_should_throw_MessageNotSentException_for_queued_messages()
        {
            using (var stream = Substitute.For <Stream>())
            {
                _streamFactory.CreateStreamAsync(null, CancellationToken.None)
                .ReturnsForAnyArgs(Task.FromResult <Stream>(stream));

                var readTcs = new TaskCompletionSource <int>();
                stream.ReadAsync(null, 0, 0, CancellationToken.None)
                .ReturnsForAnyArgs(readTcs.Task);

                var writeTcs = new TaskCompletionSource <int>();
                stream.WriteAsync(null, 0, 0, CancellationToken.None)
                .ReturnsForAnyArgs(writeTcs.Task);

                _subject.OpenAsync(CancellationToken.None).Wait();

                var message1 = new KillCursorsMessage(1, new[] { 1L });
                var task1    = _subject.SendMessageAsync(message1, _messageEncoderSettings, CancellationToken.None);

                var message2 = new KillCursorsMessage(2, new[] { 2L });
                var task2    = _subject.SendMessageAsync(message2, _messageEncoderSettings, CancellationToken.None);

                writeTcs.SetException(new SocketException());

                Action act1 = () => task1.GetAwaiter().GetResult();
                act1.ShouldThrow <SocketException>();

                Action act2 = () => task2.GetAwaiter().GetResult();
                act2.ShouldThrow <MongoMessageNotSentException>();

                _listener.ReceivedWithAnyArgs().ConnectionBeforeSendingMessages(default(ConnectionBeforeSendingMessagesEvent));
                _listener.ReceivedWithAnyArgs().ConnectionErrorSendingMessages(default(ConnectionErrorSendingMessagesEvent));
                _listener.ReceivedWithAnyArgs().ConnectionFailed(default(ConnectionFailedEvent));
            }
        }
示例#12
0
        public void SendMessageshould_throw_MongoConnectionClosedException_for_waiting_tasks(
            [Values(false, true)]
            bool async1,
            [Values(false, true)]
            bool async2)
        {
            using (var stream = Substitute.For <Stream>())
            {
                var message1 = new KillCursorsMessage(1, new[] { 1L });
                var message2 = new KillCursorsMessage(2, new[] { 2L });

                _streamFactory.CreateStream(null, CancellationToken.None)
                .ReturnsForAnyArgs(stream);
                var task1IsBlocked = false;
                var writeTcs       = new TaskCompletionSource <int>();
                stream
                .When(s => s.Write(Arg.Any <byte[]>(), Arg.Any <int>(), Arg.Any <int>()))
                .Do(_ => { task1IsBlocked = true; writeTcs.Task.GetAwaiter().GetResult(); });
                stream.WriteAsync(null, 0, 0, CancellationToken.None)
                .ReturnsForAnyArgs(_ => { task1IsBlocked = true; return(writeTcs.Task); });
                _subject.Open(CancellationToken.None);
                _capturedEvents.Clear();


                Task task1;
                if (async1)
                {
                    task1 = _subject.SendMessageAsync(message1, _messageEncoderSettings, CancellationToken.None);
                }
                else
                {
                    task1 = Task.Run(() => { _subject.SendMessage(message1, _messageEncoderSettings, CancellationToken.None); });
                }
                SpinWait.SpinUntil(() => task1IsBlocked);

                Task task2;
                if (async2)
                {
                    task2 = _subject.SendMessageAsync(message2, _messageEncoderSettings, CancellationToken.None);
                }
                else
                {
                    var task2IsRunning = false;
                    task2 = Task.Run(() => { task2IsRunning = true; _subject.SendMessage(message2, _messageEncoderSettings, CancellationToken.None); });
                    SpinWait.SpinUntil(() => task2IsRunning, 100);
                }

                writeTcs.SetException(new SocketException());

                Func <Task> act1 = () => task1;
                act1.ShouldThrow <MongoConnectionException>()
                .WithInnerException <SocketException>()
                .And.ConnectionId.Should().Be(_subject.ConnectionId);

                Func <Task> act2 = () => task2;
                act2.ShouldThrow <MongoConnectionClosedException>();

                _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesEvent>();
                _capturedEvents.Next().Should().BeOfType <CommandStartedEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesEvent>();
                _capturedEvents.Next().Should().BeOfType <CommandStartedEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionFailedEvent>();
                _capturedEvents.Next().Should().BeOfType <CommandFailedEvent>();
                _capturedEvents.Next().Should().BeOfType <CommandFailedEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesFailedEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesFailedEvent>();
                _capturedEvents.Any().Should().BeFalse();
            }
        }
示例#13
0
        public void SendMessageshould_throw_MongoConnectionClosedException_for_waiting_tasks(
            [Values(false, true)]
            bool async1,
            [Values(false, true)]
            bool async2)
        {
            var mockStream = new Mock <Stream>();

            using (mockStream.Object)
            {
                var message1 = new KillCursorsMessage(1, new[] { 1L });
                var message2 = new KillCursorsMessage(2, new[] { 2L });

                _mockStreamFactory.Setup(f => f.CreateStream(_endPoint, CancellationToken.None))
                .Returns(mockStream.Object);
                var task1IsBlocked = false;
                var writeTcs       = new TaskCompletionSource <int>();
                mockStream.Setup(s => s.Write(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>()))
                .Callback(() => { task1IsBlocked = true; writeTcs.Task.GetAwaiter().GetResult(); });
                mockStream.Setup(s => s.WriteAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()))
                .Returns(() => { task1IsBlocked = true; return(writeTcs.Task); });
                _subject.Open(CancellationToken.None);
                _capturedEvents.Clear();


                Task task1;
                if (async1)
                {
                    task1 = _subject.SendMessageAsync(message1, _messageEncoderSettings, CancellationToken.None);
                }
                else
                {
                    task1 = Task.Run(() => { _subject.SendMessage(message1, _messageEncoderSettings, CancellationToken.None); });
                }

                SpinWait.SpinUntil(() => task1IsBlocked, TimeSpan.FromSeconds(5)).Should().BeTrue();
                task1IsBlocked.Should().BeTrue();

                Task task2;
                if (async2)
                {
                    task2 = _subject.SendMessageAsync(message2, _messageEncoderSettings, CancellationToken.None);
                }
                else
                {
                    var task2IsRunning = 0;
                    task2 = Task.Run(() => { Interlocked.Exchange(ref task2IsRunning, 1); _subject.SendMessage(message2, _messageEncoderSettings, CancellationToken.None); });
                    SpinWait.SpinUntil(() => Interlocked.CompareExchange(ref task2IsRunning, 0, 0) == 1, TimeSpan.FromSeconds(5)).Should().BeTrue();
                }

                writeTcs.SetException(new SocketException());

                Func <Task> act1 = () => task1;
                act1.ShouldThrow <MongoConnectionException>()
                .WithInnerException <SocketException>()
                .And.ConnectionId.Should().Be(_subject.ConnectionId);

                Func <Task> act2 = () => task2;
                act2.ShouldThrow <MongoConnectionClosedException>();

                SpinWait.SpinUntil(() => _capturedEvents.Count >= 9, TimeSpan.FromSeconds(5));
                _capturedEvents.Count.Should().Be(9);

                var allEvents = new List <object>();
                while (_capturedEvents.Any())
                {
                    allEvents.Add(_capturedEvents.Next());
                }

                var request1Events = GetEventsForRequest(allEvents, message1.RequestId);
                request1Events.Should().HaveCount(4);
                request1Events[0].Should().BeOfType <ConnectionSendingMessagesEvent>();
                request1Events[1].Should().BeOfType <CommandStartedEvent>();
                request1Events[2].Should().BeOfType <CommandFailedEvent>();
                request1Events[3].Should().BeOfType <ConnectionSendingMessagesFailedEvent>();

                var request2Events = GetEventsForRequest(allEvents, message2.RequestId);
                request2Events.Should().HaveCount(4);
                request2Events[0].Should().BeOfType <ConnectionSendingMessagesEvent>();
                request2Events[1].Should().BeOfType <CommandStartedEvent>();
                request2Events[2].Should().BeOfType <CommandFailedEvent>();
                request2Events[3].Should().BeOfType <ConnectionSendingMessagesFailedEvent>();

                var connectionFailedEvents = allEvents.OfType <ConnectionFailedEvent>().ToList();
                connectionFailedEvents.Should().HaveCount(1);
            }
        }
示例#14
0
        public void SendMessageshould_throw_MongoConnectionClosedException_for_waiting_tasks(
            [Values(false, true)]
            bool async1,
            [Values(false, true)]
            bool async2)
        {
            var mockStream = new Mock <Stream>();

            using (mockStream.Object)
            {
                var message1 = new KillCursorsMessage(1, new[] { 1L });
                var message2 = new KillCursorsMessage(2, new[] { 2L });

                _mockStreamFactory.Setup(f => f.CreateStream(_endPoint, CancellationToken.None))
                .Returns(mockStream.Object);
                var task1IsBlocked = false;
                var writeTcs       = new TaskCompletionSource <int>();
                mockStream.Setup(s => s.Write(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>()))
                .Callback(() => { task1IsBlocked = true; writeTcs.Task.GetAwaiter().GetResult(); });
                mockStream.Setup(s => s.WriteAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>()))
                .Returns(() => { task1IsBlocked = true; return(writeTcs.Task); });
                _subject.Open(CancellationToken.None);
                _capturedEvents.Clear();


                Task task1;
                if (async1)
                {
                    task1 = _subject.SendMessageAsync(message1, _messageEncoderSettings, CancellationToken.None);
                }
                else
                {
                    task1 = Task.Run(() => { _subject.SendMessage(message1, _messageEncoderSettings, CancellationToken.None); });
                }

                SpinWait.SpinUntil(() => task1IsBlocked, 1000).Should().BeTrue();
                task1IsBlocked.Should().BeTrue();

                Task task2;
                if (async2)
                {
                    task2 = _subject.SendMessageAsync(message2, _messageEncoderSettings, CancellationToken.None);
                }
                else
                {
                    var task2IsRunning = 0;
                    task2 = Task.Run(() => { Interlocked.Exchange(ref task2IsRunning, 1); _subject.SendMessage(message2, _messageEncoderSettings, CancellationToken.None); });
                    SpinWait.SpinUntil(() => Interlocked.CompareExchange(ref task2IsRunning, 0, 0) == 1, 1000).Should().BeTrue();
                }

                writeTcs.SetException(new SocketException());

                Func <Task> act1 = () => task1;
                act1.ShouldThrow <MongoConnectionException>()
                .WithInnerException <SocketException>()
                .And.ConnectionId.Should().Be(_subject.ConnectionId);

                Func <Task> act2 = () => task2;
                act2.ShouldThrow <MongoConnectionClosedException>();

                _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesEvent>();
                _capturedEvents.Next().Should().BeOfType <CommandStartedEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesEvent>();
                _capturedEvents.Next().Should().BeOfType <CommandStartedEvent>();
                _capturedEvents.Next().Should().BeOfType <ConnectionFailedEvent>();
                _capturedEvents.Next().Should().BeOfType <CommandFailedEvent>();
                var events7And8Types = new Type[]
                {
                    _capturedEvents.Next().GetType(),
                    _capturedEvents.Next().GetType()
                };
                var expectedEventTypes = new Type[]
                {
                    typeof(CommandFailedEvent),
                    typeof(ConnectionSendingMessagesFailedEvent)
                };
                events7And8Types.Should().BeEquivalentTo(expectedEventTypes);
                _capturedEvents.Next().Should().BeOfType <ConnectionSendingMessagesFailedEvent>();
                _capturedEvents.Any().Should().BeFalse();
            }
        }