示例#1
0
        public async void TakeAsyncShouldReturnEvenWhileMoreDataArrives()
        {
            var exit       = false;
            var collection = new NagleBlockingCollection <int>(10000000);

            var sw       = Stopwatch.StartNew();
            var dataTask = collection.TakeBatch(10, TimeSpan.FromMilliseconds(5000), CancellationToken.None);


            var highVolumeAdding = Task.Factory.StartNew(async() =>
            {
                //high volume of data adds
                while (exit == false)
                {
                    await collection.AddAsync(1, CancellationToken.None);
                    Thread.Sleep(5);
                }
            });

            Console.WriteLine("Awaiting data...");
            await dataTask;

            Assert.That(dataTask.Result.Count, Is.EqualTo(10));
            Assert.That(sw.ElapsedMilliseconds, Is.LessThan(5000));
            exit = true;

            Console.WriteLine("Waiting to unwind test...");
            await highVolumeAdding;
        }
示例#2
0
        public void TakeAsyncShouldBeThreadSafe()
        {
            const int expected   = 10;
            const int max        = 100;
            var       exit       = false;
            var       collection = new NagleBlockingCollection <int>(10000000);

            var take1 = collection.TakeBatch(expected, TimeSpan.FromSeconds(100), CancellationToken.None);
            var take2 = collection.TakeBatch(expected, TimeSpan.FromSeconds(100), CancellationToken.None);
            var take3 = collection.TakeBatch(expected, TimeSpan.FromSeconds(100), CancellationToken.None);

            take1.ContinueWith(t => Console.WriteLine("Take1 done..."));
            take2.ContinueWith(t => Console.WriteLine("Take2 done..."));
            take3.ContinueWith(t => Console.WriteLine("Take3 done..."));
            Task.WhenAll(take1, take2, take3).ContinueWith(x => exit = true);

            Parallel.ForEach(Enumerable.Range(0, max).ToList(),
                             new ParallelOptions {
                MaxDegreeOfParallelism = 20
            },
                             async x =>
            {
                while (exit == false)
                {
                    await collection.AddAsync(x, CancellationToken.None);
                    Thread.Sleep(100);
                }
            });

            Console.WriteLine("Left in collection: {0}", collection.Count);
            Assert.That(take1.Result.Count, Is.EqualTo(expected));
            Assert.That(take2.Result.Count, Is.EqualTo(expected));
            Assert.That(take3.Result.Count, Is.EqualTo(expected));
            Assert.That(collection.Count, Is.LessThan(max - (expected * 3)));
        }
示例#3
0
        public void TakeAsyncShouldPlayNiceWithTPL()
        {
            const int expected   = 200;
            const int max        = 400;
            var       exit       = false;
            var       collection = new NagleBlockingCollection <int>(10000000);

            var dataTask = collection.TakeBatch(expected, TimeSpan.FromSeconds(100), CancellationToken.None);

            dataTask.ContinueWith(x => exit = true);

            Parallel.ForEach(Enumerable.Range(0, max).ToList(),
                             new ParallelOptions {
                MaxDegreeOfParallelism = 20
            },
                             async x =>
            {
                while (exit == false)
                {
                    await collection.AddAsync(x, CancellationToken.None);
                    Thread.Sleep(100);
                }
            });

            Console.WriteLine("Left in collection: {0}", collection.Count);
            Assert.That(dataTask.Result.Count, Is.EqualTo(expected));
            Assert.That(collection.Count, Is.LessThan(max - expected));
        }
        public async void CollectionAddRangeAsyncShouldBeAbleToCancel()
        {
            var collection = new NagleBlockingCollection<int>(1);
            using (var cancellationToken = new CancellationTokenSource())
            {
                var cancelledTask = collection.AddRangeAsync(Enumerable.Range(0, 5), cancellationToken.Token);
                cancellationToken.Cancel();
                await cancelledTask;
            }

        }
示例#5
0
        public async void CollectionAddRangeAsyncShouldBeAbleToCancel()
        {
            var collection = new NagleBlockingCollection <int>(1);

            using (var cancellationToken = new CancellationTokenSource())
            {
                var cancelledTask = collection.AddRangeAsync(Enumerable.Range(0, 5), cancellationToken.Token);
                cancellationToken.Cancel();
                await cancelledTask;
            }
        }
示例#6
0
        public void StoppingCollectionShouldMarkAsComplete()
        {
            var collection = new NagleBlockingCollection <int>(100);

            using (collection)
            {
                Assert.That(collection.IsCompleted, Is.False);
                collection.CompleteAdding();
                Assert.That(collection.IsCompleted, Is.True);
            }
        }
示例#7
0
        public async void TakeAsyncShouldReturnAsSoonAsBatchSizeArrived()
        {
            var collection = new NagleBlockingCollection <int>(100);

            var dataTask = collection.TakeBatch(10, TimeSpan.FromSeconds(5), CancellationToken.None);

            collection.AddRangeAsync(Enumerable.Range(0, 10), CancellationToken.None);

            await dataTask;

            Assert.That(collection.Count, Is.EqualTo(0));
        }
示例#8
0
        public async void DisposingCollectionShouldPreventMoreItemsAdded()
        {
            var collection = new NagleBlockingCollection <int>(100);

            using (collection)
            {
                await collection.AddAsync(1, CancellationToken.None);
            }

            Assert.That(collection.Count, Is.EqualTo(1));
            await collection.AddAsync(1, CancellationToken.None);
        }
示例#9
0
        public async void TakeBatchShouldRemoveItemsFromCollection()
        {
            const int expectedCount = 10;

            var collection = new NagleBlockingCollection <int>(100);
            await collection.AddRangeAsync(Enumerable.Range(0, expectedCount), CancellationToken.None);

            var data = await collection.TakeBatch(expectedCount, TimeSpan.FromMilliseconds(100), CancellationToken.None);

            Assert.That(data.Count, Is.EqualTo(expectedCount));
            Assert.That(collection.Count, Is.EqualTo(0));
        }
        public async void CollectonTakeShouldBeAbleToCancel()
        {
            var cancelSource = new CancellationTokenSource();
            var collection = new NagleBlockingCollection<int>(100);

            Task.Delay(TimeSpan.FromMilliseconds(100)).ContinueWith(t => cancelSource.Cancel());

            var sw = Stopwatch.StartNew();
            var data = await collection.TakeBatch(10, TimeSpan.FromMilliseconds(500), cancelSource.Token);
            sw.Stop();

            Assert.That(sw.ElapsedMilliseconds, Is.LessThan(300));
        }
        public void CollectionAddAsyncShouldBeAbleToCancel()
        {
            var collection = new NagleBlockingCollection<int>(1);
            using (var cancellationToken = new CancellationTokenSource())
            {
                collection.AddAsync(1, CancellationToken.None);
                var cancelledTask = collection.AddAsync(1, cancellationToken.Token);

                cancellationToken.Cancel();
                Assert.That(cancelledTask.IsCanceled, Is.True);
            }

        }
示例#12
0
        public void CollectionAddAsyncShouldBeAbleToCancel()
        {
            var collection = new NagleBlockingCollection <int>(1);

            using (var cancellationToken = new CancellationTokenSource())
            {
                collection.AddAsync(1, CancellationToken.None);
                var cancelledTask = collection.AddAsync(1, cancellationToken.Token);

                cancellationToken.Cancel();
                Assert.That(cancelledTask.IsCanceled, Is.True);
            }
        }
示例#13
0
        public async void CollectonTakeShouldBeAbleToCancel()
        {
            var cancelSource = new CancellationTokenSource();
            var collection   = new NagleBlockingCollection <int>(100);

            Task.Delay(TimeSpan.FromMilliseconds(100)).ContinueWith(t => cancelSource.Cancel());

            var sw   = Stopwatch.StartNew();
            var data = await collection.TakeBatch(10, TimeSpan.FromMilliseconds(500), cancelSource.Token);

            sw.Stop();

            Assert.That(sw.ElapsedMilliseconds, Is.LessThan(300));
        }
示例#14
0
        public async void CollectionShouldWaitXForBatchSizeToCollect()
        {
            const int expectedDelay = 100;
            const int expectedCount = 10;

            var collection = new NagleBlockingCollection <int>(100);
            await collection.AddRangeAsync(Enumerable.Range(0, expectedCount), CancellationToken.None);

            var sw   = Stopwatch.StartNew();
            var data = await collection.TakeBatch(expectedCount + 1, TimeSpan.FromMilliseconds(expectedDelay), CancellationToken.None);

            Assert.That(sw.ElapsedMilliseconds, Is.GreaterThanOrEqualTo(expectedDelay));
            Assert.That(data.Count, Is.EqualTo(expectedCount));
        }
示例#15
0
        public void CollectionShouldDisposeEvenWithQueueAddAsync()
        {
            var addTasks = new List <Task>();

            using (var collection = new NagleBlockingCollection <int>(1))
            {
                addTasks.Add(collection.AddAsync(1, CancellationToken.None));
                addTasks.Add(collection.AddAsync(1, CancellationToken.None));
                addTasks.Add(collection.AddAsync(1, CancellationToken.None));
            }

            Assert.That(addTasks[0].IsCompleted);
            Assert.False(addTasks[1].IsCompleted);
            Assert.False(addTasks[2].IsCompleted);
        }
示例#16
0
        public async void CollectionShouldReportCorrectBufferCount()
        {
            var collection = new NagleBlockingCollection <int>(100);

            var dataTask = collection.TakeBatch(10, TimeSpan.FromSeconds(5), CancellationToken.None);

            await collection.AddRangeAsync(Enumerable.Range(0, 9), CancellationToken.None);

            Assert.That(collection.Count, Is.EqualTo(9));

            collection.AddAsync(1, CancellationToken.None);
            var data = await dataTask;

            Assert.That(data.Count, Is.EqualTo(10));
            Assert.That(collection.Count, Is.EqualTo(0));
        }
示例#17
0
        /// <summary>
        /// Construct a Producer class.
        /// </summary>
        /// <param name="brokerRouter">The router used to direct produced messages to the correct partition.</param>
        /// <param name="maximumAsyncRequests">The maximum async calls allowed before blocking new requests.  -1 indicates unlimited.</param>
        /// <param name="maximumMessageBuffer">The maximum amount of messages to buffer if the async calls are blocking from sending.</param>
        /// <remarks>
        /// The maximumAsyncRequests parameter provides a mechanism for minimizing the amount of async requests in flight at any one time
        /// by blocking the caller requesting the async call.  This affectively puts an upper limit on the amount of times a caller can
        /// call SendMessageAsync before the caller is blocked.
        ///
        /// The MaximumMessageBuffer parameter provides a way to limit the max amount of memory the driver uses should the send pipeline get
        /// overwhelmed and the buffer starts to fill up.  This is an inaccurate limiting memory use as the amount of memory actually used is
        /// dependant on the general message size being buffered.
        ///
        /// A message will start its timeout countdown as soon as it is added to the producer async queue.  If there are a large number of
        /// messages sitting in the async queue then a message may spend its entire timeout cycle waiting in this queue and never getting
        /// attempted to send to Kafka before a timeout exception is thrown.
        /// </remarks>
        public Producer(IBrokerRouter brokerRouter, int maximumAsyncRequests = MaximumAsyncRequests, int maximumMessageBuffer = MaximumMessageBuffer)
        {
            BrokerRouter             = brokerRouter;
            _maximumAsyncRequests    = maximumAsyncRequests;
            _metadataQueries         = new MetadataQueries(BrokerRouter);
            _nagleBlockingCollection = new NagleBlockingCollection <TopicMessage>(maximumMessageBuffer);
            _semaphoreMaximumAsync   = new SemaphoreSlim(maximumAsyncRequests, maximumAsyncRequests);

            BatchSize      = DefaultBatchSize;
            BatchDelayTime = TimeSpan.FromMilliseconds(DefaultBatchDelayMS);

            _postTask = Task.Run(async() =>
            {
                await BatchSendAsync().ConfigureAwait(false);
                //TODO add log for ending the sending thread.
            });
        }
示例#18
0
        /// <summary>
        /// Construct a Producer class.
        /// </summary>
        /// <param name="brokerRouter">The router used to direct produced messages to the correct partition.</param>
        /// <param name="maximumAsyncRequests">The maximum async calls allowed before blocking new requests.  -1 indicates unlimited.</param>
        /// <param name="maximumMessageBuffer">The maximum amount of messages to buffer if the async calls are blocking from sending.</param>
        /// <remarks>
        /// The maximumAsyncRequests parameter provides a mechanism for minimizing the amount of async requests in flight at any one time
        /// by blocking the caller requesting the async call.  This affectively puts an upper limit on the amount of times a caller can 
        /// call SendMessageAsync before the caller is blocked.
        /// 
        /// The MaximumMessageBuffer parameter provides a way to limit the max amount of memory the driver uses should the send pipeline get
        /// overwhelmed and the buffer starts to fill up.  This is an inaccurate limiting memory use as the amount of memory actually used is 
        /// dependant on the general message size being buffered.
        /// 
        /// A message will start its timeout countdown as soon as it is added to the producer async queue.  If there are a large number of 
        /// messages sitting in the async queue then a message may spend its entire timeout cycle waiting in this queue and never getting
        /// attempted to send to Kafka before a timeout exception is thrown.
        /// </remarks>
        public Producer(IBrokerRouter brokerRouter, int maximumAsyncRequests = MaximumAsyncRequests, int maximumMessageBuffer = MaximumMessageBuffer)
        {
            BrokerRouter = brokerRouter;
            _maximumAsyncRequests = maximumAsyncRequests;
            _metadataQueries = new MetadataQueries(BrokerRouter);
            _nagleBlockingCollection = new NagleBlockingCollection<TopicMessage>(maximumMessageBuffer);
            _semaphoreMaximumAsync = new SemaphoreSlim(maximumAsyncRequests, maximumAsyncRequests);

            BatchSize = DefaultBatchSize;
            BatchDelayTime = TimeSpan.FromMilliseconds(DefaultBatchDelayMS);

            _postTask = Task.Run(async () =>
            {
                await BatchSendAsync().ConfigureAwait(false);
                //TODO add log for ending the sending thread.
            });

        }
        public async void EnsureCollectionBlocksAtCapacity()
        {
            const int blockingCount = 10;
            const int expectedCount = 5;

            var collection = new NagleBlockingCollection<int>(blockingCount);

            var addTask = Task.Factory.StartNew(() => collection.AddRangeAsync(Enumerable.Range(0, blockingCount + expectedCount), 
                CancellationToken.None).Wait());

            TaskTest.WaitFor(() => collection.Count >= blockingCount);

            Assert.That(collection.Count, Is.EqualTo(blockingCount), "The collection should only contain 10 items.");
            Assert.That(addTask.Status, Is.EqualTo(TaskStatus.Running), "The task should be blocking.");

            //unblock the collection
            await collection.TakeBatch(blockingCount, TimeSpan.FromMilliseconds(100), CancellationToken.None);

            await addTask;

            Assert.That(collection.Count, Is.EqualTo(expectedCount));
            Assert.That(addTask.Status, Is.EqualTo(TaskStatus.RanToCompletion));
        }
示例#20
0
        public async void EnsureCollectionBlocksAtCapacity()
        {
            const int blockingCount = 10;
            const int expectedCount = 5;

            var collection = new NagleBlockingCollection <int>(blockingCount);

            var addTask = Task.Factory.StartNew(() => collection.AddRangeAsync(Enumerable.Range(0, blockingCount + expectedCount),
                                                                               CancellationToken.None).Wait());

            TaskTest.WaitFor(() => collection.Count >= blockingCount);

            Assert.That(collection.Count, Is.EqualTo(blockingCount), "The collection should only contain 10 items.");
            Assert.That(addTask.Status, Is.EqualTo(TaskStatus.Running), "The task should be blocking.");

            //unblock the collection
            await collection.TakeBatch(blockingCount, TimeSpan.FromMilliseconds(100), CancellationToken.None);

            await addTask;

            Assert.That(collection.Count, Is.EqualTo(expectedCount));
            Assert.That(addTask.Status, Is.EqualTo(TaskStatus.RanToCompletion));
        }
        public async void CollectionShouldWaitXForBatchSizeToCollect()
        {
            const int expectedDelay = 100;
            const int expectedCount = 10;

            var collection = new NagleBlockingCollection<int>(100);
            await collection.AddRangeAsync(Enumerable.Range(0, expectedCount), CancellationToken.None);

            var sw = Stopwatch.StartNew();
            var data = await collection.TakeBatch(expectedCount + 1, TimeSpan.FromMilliseconds(expectedDelay), CancellationToken.None);

            Assert.That(sw.ElapsedMilliseconds, Is.GreaterThanOrEqualTo(expectedDelay));
            Assert.That(data.Count, Is.EqualTo(expectedCount));
        }
        public async void CollectionShouldReportCorrectBufferCount()
        {
            var collection = new NagleBlockingCollection<int>(100);

            var dataTask = collection.TakeBatch(10, TimeSpan.FromSeconds(5), CancellationToken.None);

            await collection.AddRangeAsync(Enumerable.Range(0, 9), CancellationToken.None);
            Assert.That(collection.Count, Is.EqualTo(9));

            collection.AddAsync(1, CancellationToken.None);
            var data = await dataTask;
            Assert.That(data.Count, Is.EqualTo(10));
            Assert.That(collection.Count, Is.EqualTo(0));
        }
        public async void TakeAsyncShouldReturnAsSoonAsBatchSizeArrived()
        {
            var collection = new NagleBlockingCollection<int>(100);

            var dataTask = collection.TakeBatch(10, TimeSpan.FromSeconds(5), CancellationToken.None);

            collection.AddRangeAsync(Enumerable.Range(0, 10), CancellationToken.None);

            await dataTask;

            Assert.That(collection.Count, Is.EqualTo(0));

        }
        public async void TakeAsyncShouldReturnEvenWhileMoreDataArrives()
        {
            var exit = false;
            var collection = new NagleBlockingCollection<int>(10000000);

            var sw = Stopwatch.StartNew();
            var dataTask = collection.TakeBatch(10, TimeSpan.FromMilliseconds(5000), CancellationToken.None);


            var highVolumeAdding = Task.Factory.StartNew(async () =>
            {
                //high volume of data adds
                while (exit == false)
                {
                    await collection.AddAsync(1, CancellationToken.None);
                    Thread.Sleep(5);
                }
            });

            Console.WriteLine("Awaiting data...");
            await dataTask;

            Assert.That(dataTask.Result.Count, Is.EqualTo(10));
            Assert.That(sw.ElapsedMilliseconds, Is.LessThan(5000));
            exit = true;

            Console.WriteLine("Waiting to unwind test...");
            await highVolumeAdding;
        }
 public void NagleBlockingCollectionConstructs()
 {
     var collection = new NagleBlockingCollection<string>(10);
     Assert.That(collection, Is.Not.Null);
 }
        public void TakeAsyncShouldPlayNiceWithTPL()
        {
            const int expected = 200;
            const int max = 400;
            var exit = false;
            var collection = new NagleBlockingCollection<int>(10000000);

            var dataTask = collection.TakeBatch(expected, TimeSpan.FromSeconds(100), CancellationToken.None);

            dataTask.ContinueWith(x => exit = true);

            Parallel.ForEach(Enumerable.Range(0, max).ToList(),
                   new ParallelOptions { MaxDegreeOfParallelism = 20 },
                   async x =>
                   {
                       while (exit == false)
                       {
                           await collection.AddAsync(x, CancellationToken.None);
                           Thread.Sleep(100);
                       }
                   });

            Console.WriteLine("Left in collection: {0}", collection.Count);
            Assert.That(dataTask.Result.Count, Is.EqualTo(expected));
            Assert.That(collection.Count, Is.LessThan(max - expected));
        }
示例#27
0
 public void CollectionShouldDisposeWithoutExceptions()
 {
     using (var collection = new NagleBlockingCollection <int>(100))
     {
     }
 }
        public void TakeAsyncShouldBeThreadSafe()
        {
            const int expected = 10;
            const int max = 100;
            var exit = false;
            var collection = new NagleBlockingCollection<int>(10000000);

            var take1 = collection.TakeBatch(expected, TimeSpan.FromSeconds(100), CancellationToken.None);
            var take2 = collection.TakeBatch(expected, TimeSpan.FromSeconds(100), CancellationToken.None);
            var take3 = collection.TakeBatch(expected, TimeSpan.FromSeconds(100), CancellationToken.None);

            take1.ContinueWith(t => Console.WriteLine("Take1 done..."));
            take2.ContinueWith(t => Console.WriteLine("Take2 done..."));
            take3.ContinueWith(t => Console.WriteLine("Take3 done..."));
            Task.WhenAll(take1, take2, take3).ContinueWith(x => exit = true);

            Parallel.ForEach(Enumerable.Range(0, max).ToList(),
                   new ParallelOptions { MaxDegreeOfParallelism = 20 },
                   async x =>
                   {
                       while (exit == false)
                       {
                           await collection.AddAsync(x, CancellationToken.None);
                           Thread.Sleep(100);
                       }
                   });

            Console.WriteLine("Left in collection: {0}", collection.Count);
            Assert.That(take1.Result.Count, Is.EqualTo(expected));
            Assert.That(take2.Result.Count, Is.EqualTo(expected));
            Assert.That(take3.Result.Count, Is.EqualTo(expected));
            Assert.That(collection.Count, Is.LessThan(max - (expected*3)));
        }
        public async void TakeBatchShouldRemoveItemsFromCollection()
        {
            const int expectedCount = 10;

            var collection = new NagleBlockingCollection<int>(100);
            await collection.AddRangeAsync(Enumerable.Range(0, expectedCount), CancellationToken.None);

            var data = await collection.TakeBatch(expectedCount, TimeSpan.FromMilliseconds(100), CancellationToken.None);

            Assert.That(data.Count, Is.EqualTo(expectedCount));
            Assert.That(collection.Count, Is.EqualTo(0));
        }
 public void StoppingCollectionShouldMarkAsComplete()
 {
     var collection = new NagleBlockingCollection<int>(100);
     using (collection)
     {
         Assert.That(collection.IsCompleted, Is.False);
         collection.CompleteAdding();
         Assert.That(collection.IsCompleted, Is.True);
     }
 }
        public async void DisposingCollectionShouldPreventMoreItemsAdded()
        {
            var collection = new NagleBlockingCollection<int>(100);
            using (collection)
            {
                await collection.AddAsync(1, CancellationToken.None);
            }

            Assert.That(collection.Count, Is.EqualTo(1));
            await collection.AddAsync(1, CancellationToken.None);
        }
示例#32
0
        public void NagleBlockingCollectionConstructs()
        {
            var collection = new NagleBlockingCollection <string>(10);

            Assert.That(collection, Is.Not.Null);
        }
        public void CollectionShouldDisposeWithoutExceptions()
        {
            using (var collection = new NagleBlockingCollection<int>(100))
            {
                
            }

        }
        public void CollectionShouldDisposeEvenWithQueueAddAsync()
        {
            var addTasks = new List<Task>();
            using (var collection = new NagleBlockingCollection<int>(1))
            {
                addTasks.Add(collection.AddAsync(1, CancellationToken.None));
                addTasks.Add(collection.AddAsync(1, CancellationToken.None));
                addTasks.Add(collection.AddAsync(1, CancellationToken.None));
            }

            Assert.That(addTasks[0].IsCompleted);
            Assert.False(addTasks[1].IsCompleted);
            Assert.False(addTasks[2].IsCompleted);
        }