Beispiel #1
0
        public async Task GetBatchWhenLimitIsReached(int batchCount)
        {
            var q = new AsyncBatchQueue <string>(10000,
                                                 new long[] { batchCount },
                                                 new Func <string, long>[] { s => 1 });

            var output = new List <string>();

            for (var i = 0; i < batchCount + 1; i++)
            {
                await q.PushAsync("a");
            }

            var getTask = q.GetNextBatchAsync(output, 10 * 1000).AsTask();

            // first call should returns a full batch
            Assert.True(getTask.Wait(1000));
            Assert.Equal(batchCount, output.Count);

            if (batchCount == 0)
            {
                return;
            }
            // second call should return the last item
            output.Clear();
            await q.GetNextBatchAsync(output, 100);

            Assert.Single(output);
        }
Beispiel #2
0
        public async Task InMemoryQueue_PushAndGet(int batchCount)
        {
            var secondary = new InMemoryQueue <List <string> >(10);

            var q = new AsyncBatchQueue <string>(1000,
                                                 new long[] { batchCount },
                                                 new Func <string, long>[] { s => 1 }, secondary);

            await q.PushSecondaryAsync(Enumerable.Repeat("a", batchCount + 1).ToList());

            var output  = new List <string>();
            var getTask = q.GetNextBatchAsync(output, 10 * 1000).AsTask();

            Assert.True(getTask.Wait(1000));
            Assert.Equal(batchCount, output.Count);

            if (batchCount == 0)
            {
                return;
            }

            // second call should return the last item
            output.Clear();
            await q.GetNextBatchAsync(output, 100);

            Assert.Single(output);
        }
Beispiel #3
0
        public async Task InMemoryQueue_ConcurrentRead(int readerCount, int itemCount)
        {
            var secondary = new InMemoryQueue <List <int> >(1000);

            using var cts       = new CancellationTokenSource();
            using var semaphore = new SemaphoreSlim(0, readerCount);
            var results = new List <int>();
            var q       = new AsyncBatchQueue <int>(10000,
                                                    new long[] { 100 },
                                                    new Func <int, long>[] { s => 1 }, secondary);

            async Task readerTask()
            {
                var output = new List <int>();

                await semaphore.WaitAsync();

                // we're trying to test that the readers will 'eventually' read all the items, so we do several pulls here
                await q.GetNextBatchAsync(output, 500);

                await q.GetNextBatchAsync(output, 500);

                await q.GetNextBatchAsync(output, 500);

                await Task.Delay(100);

                lock (results)
                {
                    results.AddRange(output);
                }
            };

            var readers = new Task[readerCount];

            for (var i = 0; i < readerCount; i++)
            {
                readers[i] = readerTask();
            }

            for (var i = 0; i < itemCount; i++)
            {
                if (i % 2 == 0)
                {
                    await q.PushAsync(i);
                }
                else
                {
                    await q.PushSecondaryAsync(new List <int> {
                        i
                    });
                }
            }
            semaphore.Release(readerCount);
            await Task.WhenAll(readers);

            _output.WriteLine(results.Count.ToString());
            _output.WriteLine(q.EstimateSize().ToString());
            _output.WriteLine(q.EstimateSecondaryQueueSize().ToString());
            Assert.Equal(itemCount, results.Distinct().Count());
        }
Beispiel #4
0
        public async Task InMemoryQueue_PullBothQueues()
        {
            var secondary = new InMemoryQueue <List <int> >(10);

            var q = new AsyncBatchQueue <int>(500,
                                              new long[] { 500 },
                                              new Func <int, long>[] { s => 1 }, secondary);

            await q.PushSecondaryAsync(Enumerable.Range(0, 500).ToList());

            for (var i = 500; i < 1000; i++)
            {
                await q.PushAsync(i);
            }

            // pull 3 times
            var output = new List <int>();
            await q.GetNextBatchAsync(output, 1000);

            await q.GetNextBatchAsync(output, 1000);

            await q.GetNextBatchAsync(output, 1000);

            Assert.Equal(1000, output.Distinct().Count());
        }
Beispiel #5
0
        public async Task PersistentQueue_PushAndGet(int batchCount)
        {
            var dataDir  = Path.Combine(AppContext.BaseDirectory, Guid.NewGuid().ToString());
            var queueDir = Path.Combine(dataDir, _queueDirName);

            Directory.CreateDirectory(queueDir);
            var fileProvider = new ProtectedAppDataFileProvider(dataDir);

            try
            {
                var secondary = new FilePersistentQueue <List <int> >(100, queueDir, new IntegerListSerializer(), fileProvider, NullLogger.Instance);

                var q = new AsyncBatchQueue <int>(1000,
                                                  new long[] { batchCount },
                                                  new Func <int, long>[] { s => 1 }, secondary);

                await q.PushSecondaryAsync(Enumerable.Range(0, batchCount + 1).ToList());

                var output  = new List <int>();
                var getTask = q.GetNextBatchAsync(output, 10 * 1000).AsTask();
                Assert.True(getTask.Wait(1000));
                Assert.Equal(batchCount, output.Count);

                if (batchCount == 0)
                {
                    return;
                }

                // second call should return the last item
                output.Clear();
                await q.GetNextBatchAsync(output, 100);

                Assert.Single(output);
            }
            finally
            {
                if (Directory.Exists(dataDir))
                {
                    Directory.Delete(dataDir, true);
                }
            }
        }
Beispiel #6
0
        public async Task PersistentQueue_PullBothQueues()
        {
            var dataDir  = Path.Combine(AppContext.BaseDirectory, Guid.NewGuid().ToString());
            var queueDir = Path.Combine(dataDir, _queueDirName);

            Directory.CreateDirectory(queueDir);
            var fileProvider = new ProtectedAppDataFileProvider(dataDir);

            try
            {
                var secondary = new FilePersistentQueue <List <int> >(10, queueDir, new IntegerListSerializer(), fileProvider, NullLogger.Instance);
                var q         = new AsyncBatchQueue <int>(500,
                                                          new long[] { 500 },
                                                          new Func <int, long>[] { s => 1 }, secondary);

                await q.PushSecondaryAsync(Enumerable.Range(0, 500).ToList());

                for (var i = 500; i < 1000; i++)
                {
                    await q.PushAsync(i);
                }

                // pull 3 times
                var output = new List <int>();
                await q.GetNextBatchAsync(output, 1000);

                await q.GetNextBatchAsync(output, 1000);

                await q.GetNextBatchAsync(output, 1000);

                Assert.Equal(1000, output.Distinct().Count());
            }
            finally
            {
                if (Directory.Exists(dataDir))
                {
                    Directory.Delete(dataDir, true);
                }
            }
        }
Beispiel #7
0
        public async Task LimitIsReached_OrderIsPresevered()
        {
            var q = new AsyncBatchQueue <int>(10000,
                                              new long[] { 100 },
                                              new Func <int, long>[] { s => 1 });

            for (var i = 0; i < 150 + 1; i++)
            {
                await q.PushAsync(i);
            }

            var output = new List <int>();
            await q.GetNextBatchAsync(output, 1000);

            // pull again
            await q.GetNextBatchAsync(output, 100);

            for (var i = 0; i < 150; i++)
            {
                Assert.Equal(i, output[i]);
            }
        }
Beispiel #8
0
        public async Task GetBatchWhenTimerExpires(int batchCount, int remaining)
        {
            var q = new AsyncBatchQueue <string>(10000,
                                                 new long[] { batchCount },
                                                 new Func <string, long>[] { s => 1 });

            var output = new List <string>();

            for (var i = 0; i < batchCount - remaining; i++)
            {
                await q.PushAsync("a");
            }

            var getTask = q.GetNextBatchAsync(output, 500).AsTask();

            Assert.True(getTask.Wait(5000));
            Assert.Equal(batchCount - remaining, output.Count);
        }
Beispiel #9
0
        public async Task GetBatch_Cancellation()
        {
            using var cts = new CancellationTokenSource();
            var output = new List <string>();
            var q      = new AsyncBatchQueue <string>(10000,
                                                      new long[] { 100 },
                                                      new Func <string, long>[] { s => 1 });

            for (var i = 0; i < 99; i++)
            {
                await q.PushAsync("a");
            }

            var getTask = q.GetNextBatchAsync(output, int.MaxValue, cts.Token).AsTask();

            cts.Cancel();

            await Task.Delay(200);

            Assert.True(getTask.IsCompleted);
        }
Beispiel #10
0
        public async Task PersistentQueue_ConcurrentRead(int readerCount, int itemCount)
        {
            var dataDir  = Path.Combine(AppContext.BaseDirectory, Guid.NewGuid().ToString());
            var queueDir = Path.Combine(dataDir, _queueDirName);

            Directory.CreateDirectory(queueDir);
            var fileProvider = new ProtectedAppDataFileProvider(dataDir);

            try
            {
                var secondary = new FilePersistentQueue <List <int> >(100000, queueDir, new IntegerListSerializer(), fileProvider, NullLogger.Instance);
                using var cts       = new CancellationTokenSource();
                using var semaphore = new SemaphoreSlim(0, readerCount);
                var results = new List <int>();
                var q       = new AsyncBatchQueue <int>(10000,
                                                        new long[] { 100 },
                                                        new Func <int, long>[] { s => 1 }, secondary);

                async Task readerTask()
                {
                    var output = new List <int>();

                    await semaphore.WaitAsync();

                    // we're trying to test that the readers will 'eventually' read all the items, so we do several pulls here
                    await q.GetNextBatchAsync(output, 500);

                    await q.GetNextBatchAsync(output, 500);

                    await q.GetNextBatchAsync(output, 500);

                    await Task.Delay(100);

                    lock (results)
                    {
                        results.AddRange(output);
                    }
                };

                var readers = new Task[readerCount];
                for (var i = 0; i < readerCount; i++)
                {
                    readers[i] = readerTask();
                }

                for (var i = 0; i < itemCount; i++)
                {
                    if (i % 2 == 0)
                    {
                        await q.PushAsync(i);
                    }
                    else
                    {
                        await q.PushSecondaryAsync(new List <int> {
                            i
                        });
                    }
                }

                semaphore.Release(readerCount);
                await Task.WhenAll(readers);

                _output.WriteLine(results.Count.ToString());
                _output.WriteLine(q.EstimateSize().ToString());
                _output.WriteLine(q.EstimateSecondaryQueueSize().ToString());
                Assert.Equal(itemCount, results.Distinct().Count());
            }
            finally
            {
                if (Directory.Exists(dataDir))
                {
                    Directory.Delete(dataDir, true);
                }
            }
        }