private StreamPosition GetStreamPosition(TestQueueMessage queueMessage)
        {
            IStreamIdentity     streamIdentity = new StreamIdentity(queueMessage.StreamGuid, null);
            StreamSequenceToken sequenceToken  = queueMessage.SequenceToken;

            return(new StreamPosition(streamIdentity, sequenceToken));
        }
Пример #2
0
            private ArraySegment <byte> SerializeMessageIntoPooledSegment(TestQueueMessage queueMessage)
            {
                // serialize payload
                int size = SegmentBuilder.CalculateAppendSize(queueMessage.Data);

                // get segment from current block
                ArraySegment <byte> segment;

                if (currentBuffer == null || !currentBuffer.TryGetSegment(size, out segment))
                {
                    // no block or block full, get new block and try again
                    currentBuffer = bufferPool.Allocate();
                    //call EvictionStrategy's OnBlockAllocated method
                    this.evictionStrategy.OnBlockAllocated(currentBuffer);
                    // if this fails with clean block, then requested size is too big
                    if (!currentBuffer.TryGetSegment(size, out segment))
                    {
                        string errmsg = String.Format(CultureInfo.InvariantCulture,
                                                      "Message size is too big. MessageSize: {0}", size);
                        throw new ArgumentOutOfRangeException(nameof(queueMessage), errmsg);
                    }
                }
                // encode namespace, offset, partitionkey, properties and payload into segment
                int writeOffset = 0;

                SegmentBuilder.Append(segment, ref writeOffset, queueMessage.Data);
                return(segment);
            }
        private StreamPosition GetStreamPosition(TestQueueMessage queueMessage)
        {
            var streamId = StreamId.Create(null, queueMessage.StreamGuid);
            StreamSequenceToken sequenceToken = queueMessage.SequenceToken;

            return(new StreamPosition(streamId, sequenceToken));
        }
Пример #4
0
        public void SimpleCacheMiss()
        {
            var bufferPool       = new ObjectPool <FixedSizeBuffer>(() => new FixedSizeBuffer(PooledBufferSize));
            var dataAdapter      = new TestCacheDataAdapter();
            var cache            = new PooledQueueCache(dataAdapter, NullLogger.Instance, null, null, TimeSpan.FromSeconds(10));
            var evictionStrategy = new ChronologicalEvictionStrategy(NullLogger.Instance, new TimePurgePredicate(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)), null, null);

            evictionStrategy.PurgeObservable = cache;
            var converter = new CachedMessageConverter(bufferPool, evictionStrategy);

            var seqNumber = 123;
            var streamKey = Guid.NewGuid();
            var stream    = StreamId.Create(TestStreamNamespace, streamKey);

            var cursor = cache.GetCursor(stream, new EventSequenceTokenV2(seqNumber));

            // Start by enqueuing a message for stream, followed bu another one destined for another one
            EnqueueMessage(streamKey);
            EnqueueMessage(Guid.NewGuid());
            // Consume the stream, should be fine
            Assert.True(cache.TryGetNextMessage(cursor, out _));
            Assert.False(cache.TryGetNextMessage(cursor, out _));

            // Enqueue a new batch
            // First and last messages destined for stream, following messages
            // destined for other streams
            EnqueueMessage(streamKey);
            for (var idx = 0; idx < 20; idx++)
            {
                EnqueueMessage(Guid.NewGuid());
            }

            // Remove first three messages from the cache
            cache.RemoveOldestMessage(); // Destined for stream, consumed
            cache.RemoveOldestMessage(); // Not destined for stream
            cache.RemoveOldestMessage(); // Destined for stream, not consumed

            // Enqueue a new message for stream
            EnqueueMessage(streamKey);

            // Should throw since we missed the second message destined for stream
            Assert.Throws <QueueCacheMissException>(() => cache.TryGetNextMessage(cursor, out _));

            long EnqueueMessage(Guid streamId)
            {
                var now = DateTime.UtcNow;
                var msg = new TestQueueMessage
                {
                    StreamId       = StreamId.Create(TestStreamNamespace, streamId),
                    SequenceNumber = seqNumber,
                };

                cache.Add(new List <CachedMessage>()
                {
                    converter.ToCachedMessage(msg, now)
                }, now);
                seqNumber++;
                return(msg.SequenceNumber);
            }
        }
Пример #5
0
        public async Task EnqueueAbandonDequeue()
        {
            // create a test queue
            Queue testQueue = await this.CreateQueue();

            // send a test message
            TestQueueMessage sendMessage = await this.SendMessage(testQueue);

            // receive it
            TestQueueMessage recvMessage = (TestQueueMessage)await testQueue.ReceiveAsync();

            // compare it
            Assert.IsTrue(sendMessage.Equals(recvMessage));

            // abandon it
            await testQueue.AbandonAsync(recvMessage);

            // receive it again
            TestQueueMessage recvMessage2 = (TestQueueMessage)await testQueue.ReceiveAsync();

            // compare it
            Assert.IsTrue(sendMessage.Equals(recvMessage2));

            // delete message
            await testQueue.CompleteAsync(recvMessage2);

            // delete queue
            await this.sb.DeleteQueueAsync(this.queueName);
        }
Пример #6
0
            private StreamPosition GetStreamPosition(TestQueueMessage queueMessage)
            {
                IStreamIdentity     streamIdentity = new StreamIdentity(queueMessage.StreamGuid, queueMessage.StreamNamespace);
                StreamSequenceToken sequenceToken  = new EventSequenceTokenV2(queueMessage.SequenceNumber);

                return(new StreamPosition(streamIdentity, sequenceToken));
            }
Пример #7
0
        public void NextInStreamTest()
        {
            IObjectPool <CachedMessageBlock <TestCachedMessage> >   pool        = new MyTestPooled();
            ICacheDataAdapter <TestQueueMessage, TestCachedMessage> dataAdapter = new TestCacheDataAdapter();
            CachedMessageBlock <TestCachedMessage> block = pool.Allocate();
            int last           = 0;
            int sequenceNumber = 0;
            // define 2 streams
            var streams = new[] { new StreamIdentity(Guid.NewGuid(), null), new StreamIdentity(Guid.NewGuid(), null) };

            // add both streams interleaved, until lock is full
            while (block.HasCapacity)
            {
                var stream  = streams[last % 2];
                var message = new TestQueueMessage
                {
                    StreamGuid    = stream.Guid,
                    SequenceToken = new EventSequenceToken(sequenceNumber)
                };

                // add message to end of block
                AddAndCheck(block, dataAdapter, message, 0, last - 1);
                last++;
                sequenceNumber += 2;
            }

            // get index of first stream
            int streamIndex;

            Assert.True(block.TryFindFirstMessage(streams[0], TestCacheDataComparer.Instance, out streamIndex));
            Assert.Equal(0, streamIndex);
            Assert.Equal(0, (block.GetSequenceToken(streamIndex, dataAdapter) as EventSequenceToken).SequenceNumber);

            // find stream1 messages
            int iteration = 1;

            while (block.TryFindNextMessage(streamIndex + 1, streams[0], TestCacheDataComparer.Instance, out streamIndex))
            {
                Assert.Equal(iteration * 2, streamIndex);
                Assert.Equal(iteration * 4, (block.GetSequenceToken(streamIndex, dataAdapter) as EventSequenceToken).SequenceNumber);
                iteration++;
            }
            Assert.Equal(iteration, TestBlockSize / 2);

            // get index of first stream
            Assert.True(block.TryFindFirstMessage(streams[1], TestCacheDataComparer.Instance, out streamIndex));
            Assert.Equal(1, streamIndex);
            Assert.Equal(2, (block.GetSequenceToken(streamIndex, dataAdapter) as EventSequenceToken).SequenceNumber);

            // find stream1 messages
            iteration = 1;
            while (block.TryFindNextMessage(streamIndex + 1, streams[1], TestCacheDataComparer.Instance, out streamIndex))
            {
                Assert.Equal(iteration * 2 + 1, streamIndex);
                Assert.Equal(iteration * 4 + 2, (block.GetSequenceToken(streamIndex, dataAdapter) as EventSequenceToken).SequenceNumber);
                iteration++;
            }
            Assert.Equal(iteration, TestBlockSize / 2);
        }
Пример #8
0
        public void AvoidCacheMissMultipleStreamsActive()
        {
            var bufferPool       = new ObjectPool <FixedSizeBuffer>(() => new FixedSizeBuffer(PooledBufferSize));
            var dataAdapter      = new TestCacheDataAdapter();
            var cache            = new PooledQueueCache(dataAdapter, NullLogger.Instance, null, null, TimeSpan.FromSeconds(30));
            var evictionStrategy = new ChronologicalEvictionStrategy(NullLogger.Instance, new TimePurgePredicate(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)), null, null);

            evictionStrategy.PurgeObservable = cache;
            var converter = new CachedMessageConverter(bufferPool, evictionStrategy);

            var seqNumber = 123;
            var streamKey = Guid.NewGuid();
            var stream    = StreamId.Create(TestStreamNamespace, streamKey);

            // Enqueue a message for our stream
            var firstSequenceNumber = EnqueueMessage(streamKey);

            // Enqueue a few other messages for other streams
            EnqueueMessage(Guid.NewGuid());
            EnqueueMessage(Guid.NewGuid());

            // Consume the first event and see that the cursor has moved to last seen event (not matching our streamIdentity)
            var cursor = cache.GetCursor(stream, new EventSequenceTokenV2(firstSequenceNumber));

            Assert.True(cache.TryGetNextMessage(cursor, out var firstContainer));
            Assert.False(cache.TryGetNextMessage(cursor, out _));

            // Remove multiple events, including the one that the cursor is currently pointing to
            cache.RemoveOldestMessage();
            cache.RemoveOldestMessage();
            cache.RemoveOldestMessage();

            // Enqueue another message for stream
            var lastSequenceNumber = EnqueueMessage(streamKey);

            // Should be able to consume the event just pushed
            Assert.True(cache.TryGetNextMessage(cursor, out var lastContainer));
            Assert.Equal(stream, lastContainer.StreamId);
            Assert.Equal(lastSequenceNumber, lastContainer.SequenceToken.SequenceNumber);

            long EnqueueMessage(Guid streamId)
            {
                var now = DateTime.UtcNow;
                var msg = new TestQueueMessage
                {
                    StreamId       = StreamId.Create(TestStreamNamespace, streamId),
                    SequenceNumber = seqNumber,
                };

                cache.Add(new List <CachedMessage>()
                {
                    converter.ToCachedMessage(msg, now)
                }, now);
                seqNumber++;
                return(msg.SequenceNumber);
            }
        }
Пример #9
0
        private void AddAndCheck(CachedMessageBlock <TestCachedMessage> block, ICacheDataAdapter <TestQueueMessage, TestCachedMessage> dataAdapter, int first, int last, int sequenceNumber = 1)
        {
            var message = new TestQueueMessage
            {
                StreamGuid    = StreamGuid,
                SequenceToken = new EventSequenceToken(sequenceNumber)
            };

            AddAndCheck(block, dataAdapter, message, first, last);
        }
        private CachedMessage QueueMessageToCachedMessage(TestQueueMessage queueMessage, DateTime dequeueTimeUtc)
        {
            StreamPosition streamPosition = GetStreamPosition(queueMessage);

            return(new CachedMessage
            {
                StreamGuid = streamPosition.StreamIdentity.Guid,
                SequenceNumber = queueMessage.SequenceToken.SequenceNumber,
                EventIndex = queueMessage.SequenceToken.EventIndex,
            });
        }
Пример #11
0
            /// <summary>
            /// Is this object equal?
            /// </summary>
            /// <param name="t">object to compare to</param>
            /// <returns>true if equal, false otherwise</returns>
            public bool Equals(TestQueueMessage t)
            {
                // If parameter is null return false:
                if ((object)t == null)
                {
                    return(false);
                }

                // Return true if the fields match:
                return((this.TestString == t.TestString) && (this.TestInt == t.TestInt) && (this.TestBool == t.TestBool));
            }
Пример #12
0
        public void SimpleCacheMiss()
        {
            var bufferPool       = new ObjectPool <FixedSizeBuffer>(() => new FixedSizeBuffer(PooledBufferSize));
            var dataAdapter      = new TestCacheDataAdapter();
            var cache            = new PooledQueueCache(dataAdapter, NullLogger.Instance, null, null, TimeSpan.FromSeconds(10));
            var evictionStrategy = new ChronologicalEvictionStrategy(NullLogger.Instance, new TimePurgePredicate(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)), null, null);

            evictionStrategy.PurgeObservable = cache;
            var converter = new CachedMessageConverter(bufferPool, evictionStrategy);

            int idx;
            var seqNumber = 123;
            var stream    = StreamId.Create(TestStreamNamespace, Guid.NewGuid());

            // First and last messages destined for stream, following messages
            // destined for other streams
            for (idx = 0; idx < 20; idx++)
            {
                var now = DateTime.UtcNow;
                var msg = new TestQueueMessage
                {
                    StreamId       = (idx == 0) ? stream : StreamId.Create(TestStreamNamespace, Guid.NewGuid()),
                    SequenceNumber = seqNumber + idx,
                };
                cache.Add(new List <CachedMessage>()
                {
                    converter.ToCachedMessage(msg, now)
                }, now);
            }

            var cursor = cache.GetCursor(stream, new EventSequenceTokenV2(seqNumber));

            // Remove first message
            cache.RemoveOldestMessage();

            // Enqueue a new message for stream
            {
                idx++;
                var now = DateTime.UtcNow;
                var msg = new TestQueueMessage
                {
                    StreamId       = stream,
                    SequenceNumber = seqNumber + idx,
                };
                cache.Add(new List <CachedMessage>()
                {
                    converter.ToCachedMessage(msg, now)
                }, now);
            }

            // Should throw since we missed the first message
            Assert.Throws <QueueCacheMissException>(() => cache.TryGetNextMessage(cursor, out _));
        }
Пример #13
0
            public CachedMessage ToCachedMessage(TestQueueMessage queueMessage, DateTime dequeueTimeUtc)
            {
                StreamPosition streamPosition = GetStreamPosition(queueMessage);

                return(new CachedMessage
                {
                    StreamId = streamPosition.StreamId,
                    SequenceNumber = queueMessage.SequenceNumber,
                    EnqueueTimeUtc = queueMessage.EnqueueTimeUtc,
                    DequeueTimeUtc = dequeueTimeUtc,
                    Segment = SerializeMessageIntoPooledSegment(queueMessage),
                });
            }
Пример #14
0
            public CachedMessage ToCachedMessage(TestQueueMessage queueMessage, DateTime dequeueTimeUtc)
            {
                StreamPosition streamPosition = GetStreamPosition(queueMessage);

                return(new CachedMessage
                {
                    StreamGuid = streamPosition.StreamIdentity.Guid,
                    StreamNamespace = streamPosition.StreamIdentity.Namespace != null?string.Intern(streamPosition.StreamIdentity.Namespace) : null,
                                          SequenceNumber = queueMessage.SequenceNumber,
                                          EnqueueTimeUtc = queueMessage.EnqueueTimeUtc,
                                          DequeueTimeUtc = dequeueTimeUtc,
                                          Segment = SerializeMessageIntoPooledSegment(queueMessage),
                });
            }
Пример #15
0
            /// <summary>
            /// Is this object equal?
            /// </summary>
            /// <param name="obj">object to compare to</param>
            /// <returns>true if equal, false otherwise</returns>
            public override bool Equals(object obj)
            {
                // If parameter is null return false.
                if (obj == null)
                {
                    return(false);
                }

                // If parameter cannot be cast to TestQueueMessage return false.
                TestQueueMessage t = obj as TestQueueMessage;

                if ((object)t == null)
                {
                    return(false);
                }

                // Return true if the fields match:
                return((this.TestString == t.TestString) && (this.TestInt == t.TestInt) && (this.TestBool == t.TestBool));
            }
        public void TestInitialize()
        {
            // Arrange
            var azureStorageQueueConfig = new AzureStorageQueueConfig
            {
                ConnectionString = AzureStorageData.ConnectionString,
                QueueName        = "osw-lib-dataaccess-azurestorage"
            };

            this.azureStorageQueue = AzureStorageQueueFactory.Create(
                this.LoggerFactoryEnriched,
                azureStorageQueueConfig);

            this.azureStorageQueue.CreateIfNotExists();

            this.testQueueMessage = new TestQueueMessage
            {
                Author = OrisicSoftworks
            };
        }
Пример #17
0
        /// <summary>
        /// Create and send a queue message
        /// </summary>
        /// <param name="queue">queue to send it to</param>
        /// <returns>queue message that was sent</returns>
        private async Task <TestQueueMessage> SendMessage(Queue queue)
        {
            // values to be used inside a queue message
            string testMessageString = "sharad";
            int    testMessageInt    = new Random().Next();
            bool   testMessageBool   = true;

            // create a test message
            var m = new TestQueueMessage();

            m.TestString = testMessageString;
            m.TestInt    = testMessageInt;
            m.TestBool   = testMessageBool;

            // send the test message
            await queue.SendAsync(m);

            // return the message
            return(m);
        }
Пример #18
0
        private void AddAndCheck(CachedMessageBlock <TestQueueMessage, TestCachedMessage> block, TestQueueMessage message, int first, int last)
        {
            Assert.AreEqual(first, block.OldestMessageIndex);
            Assert.AreEqual(last, block.NewestMessageIndex);
            Assert.IsTrue(block.HasCapacity);

            block.Add(message);
            last++;

            Assert.AreEqual(first > last, block.IsEmpty);
            Assert.AreEqual(last + 1 < TestBlockSize, block.HasCapacity);
            Assert.AreEqual(first, block.OldestMessageIndex);
            Assert.AreEqual(last, block.NewestMessageIndex);

            Assert.IsTrue(block.GetSequenceToken(last).Equals(message.SequenceToken));
        }
Пример #19
0
        private void AvoidCacheMiss(bool emptyCache)
        {
            var bufferPool       = new ObjectPool <FixedSizeBuffer>(() => new FixedSizeBuffer(PooledBufferSize));
            var dataAdapter      = new TestCacheDataAdapter();
            var cache            = new PooledQueueCache(dataAdapter, NullLogger.Instance, null, null, TimeSpan.FromSeconds(30));
            var evictionStrategy = new ChronologicalEvictionStrategy(NullLogger.Instance, new TimePurgePredicate(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)), null, null);

            evictionStrategy.PurgeObservable = cache;
            var converter = new CachedMessageConverter(bufferPool, evictionStrategy);

            var seqNumber = 123;
            var stream    = StreamId.Create(TestStreamNamespace, Guid.NewGuid());

            // Enqueue a message for stream
            var firstSequenceNumber = EnqueueMessage(stream);

            // Consume first event
            var cursor = cache.GetCursor(stream, new EventSequenceTokenV2(firstSequenceNumber));

            Assert.True(cache.TryGetNextMessage(cursor, out var firstContainer));
            Assert.Equal(stream, firstContainer.StreamId);
            Assert.Equal(firstSequenceNumber, firstContainer.SequenceToken.SequenceNumber);

            // Remove first message, that was consumed
            cache.RemoveOldestMessage();

            if (!emptyCache)
            {
                // Enqueue something not related to the stream
                // so the cache isn't empty
                EnqueueMessage(StreamId.Create(TestStreamNamespace, Guid.NewGuid()));
                EnqueueMessage(StreamId.Create(TestStreamNamespace, Guid.NewGuid()));
                EnqueueMessage(StreamId.Create(TestStreamNamespace, Guid.NewGuid()));
                EnqueueMessage(StreamId.Create(TestStreamNamespace, Guid.NewGuid()));
                EnqueueMessage(StreamId.Create(TestStreamNamespace, Guid.NewGuid()));
                EnqueueMessage(StreamId.Create(TestStreamNamespace, Guid.NewGuid()));
            }

            // Enqueue another message for stream
            var lastSequenceNumber = EnqueueMessage(stream);

            // Should be able to consume the event just pushed
            Assert.True(cache.TryGetNextMessage(cursor, out var lastContainer));
            Assert.Equal(stream, lastContainer.StreamId);
            Assert.Equal(lastSequenceNumber, lastContainer.SequenceToken.SequenceNumber);

            long EnqueueMessage(StreamId streamId)
            {
                var now = DateTime.UtcNow;
                var msg = new TestQueueMessage
                {
                    StreamId       = streamId,
                    SequenceNumber = seqNumber,
                };

                cache.Add(new List <CachedMessage>()
                {
                    converter.ToCachedMessage(msg, now)
                }, now);
                seqNumber++;
                return(msg.SequenceNumber);
            }
        }
Пример #20
0
        private void AddAndCheck(CachedMessageBlock <TestCachedMessage> block, ICacheDataAdapter <TestQueueMessage, TestCachedMessage> dataAdapter, TestQueueMessage message, int first, int last)
        {
            Assert.Equal(first, block.OldestMessageIndex);
            Assert.Equal(last, block.NewestMessageIndex);
            Assert.True(block.HasCapacity);

            block.Add(message, DateTime.UtcNow, dataAdapter);
            last++;

            Assert.Equal(first > last, block.IsEmpty);
            Assert.Equal(last + 1 < TestBlockSize, block.HasCapacity);
            Assert.Equal(first, block.OldestMessageIndex);
            Assert.Equal(last, block.NewestMessageIndex);

            Assert.True(block.GetSequenceToken(last, dataAdapter).Equals(message.SequenceToken));
        }
Пример #21
0
            private StreamPosition GetStreamPosition(TestQueueMessage queueMessage)
            {
                StreamSequenceToken sequenceToken = new EventSequenceTokenV2(queueMessage.SequenceNumber);

                return(new StreamPosition(queueMessage.StreamId, sequenceToken));
            }