Example #1
0
        public async Task CanRunWorkItemJobUntilEmpty()
        {
            using (var queue = new InMemoryQueue <WorkItemData>(new InMemoryQueueOptions <WorkItemData> {
                LoggerFactory = Log
            })) {
                using (var messageBus = new InMemoryMessageBus(new InMemoryMessageBusOptions {
                    LoggerFactory = Log
                })) {
                    var handlerRegistry = new WorkItemHandlers();
                    var job             = new WorkItemJob(queue, messageBus, handlerRegistry, Log);

                    handlerRegistry.Register <MyWorkItem>(new MyWorkItemHandler(Log));

                    await queue.EnqueueAsync(new MyWorkItem {
                        SomeData = "Test"
                    }, true);

                    await queue.EnqueueAsync(new MyWorkItem {
                        SomeData = "Test"
                    }, true);

                    await job.RunUntilEmptyAsync();

                    var stats = await queue.GetQueueStatsAsync();

                    Assert.Equal(2, stats.Enqueued);
                    Assert.Equal(2, stats.Dequeued);
                    Assert.Equal(2, stats.Completed);
                }
            }
        }
Example #2
0
        public async Task CanRunBadWorkItem()
        {
            using (var queue = new InMemoryQueue <WorkItemData>(new InMemoryQueueOptions <WorkItemData> {
                RetryDelay = TimeSpan.FromMilliseconds(500), LoggerFactory = Log
            })) {
                using (var messageBus = new InMemoryMessageBus(new InMemoryMessageBusOptions {
                    LoggerFactory = Log
                })) {
                    var handlerRegistry = new WorkItemHandlers();
                    var job             = new WorkItemJob(queue, messageBus, handlerRegistry, Log);

                    handlerRegistry.Register <MyWorkItem>(ctx => {
                        var jobData = ctx.GetData <MyWorkItem>();
                        Assert.Equal("Test", jobData.SomeData);
                        throw new Exception();
                    });

                    string jobId = await queue.EnqueueAsync(new MyWorkItem {
                        SomeData = "Test"
                    }, true);

                    int statusCount = 0;
                    await messageBus.SubscribeAsync <WorkItemStatus>(status => {
                        _logger.Trace("Progress: {progress}", status.Progress);
                        Assert.Equal(jobId, status.WorkItemId);
                        statusCount++;
                    });

                    await job.RunUntilEmptyAsync();

                    Assert.Equal(1, statusCount);
                }
            }
        }
Example #3
0
        public async Task CanRunWorkItem()
        {
            using (var queue = new InMemoryQueue <WorkItemData>()) {
                using (var messageBus = new InMemoryMessageBus()) {
                    var handlerRegistry = new WorkItemHandlers();
                    var job             = new WorkItemJob(queue, messageBus, handlerRegistry, Log);

                    handlerRegistry.Register <MyWorkItem>(async ctx => {
                        var jobData = ctx.GetData <MyWorkItem>();
                        Assert.Equal("Test", jobData.SomeData);

                        for (int i = 0; i < 10; i++)
                        {
                            await SystemClock.SleepAsync(100);
                            await ctx.ReportProgressAsync(10 * i);
                        }
                    });

                    var jobId = await queue.EnqueueAsync(new MyWorkItem {
                        SomeData = "Test"
                    }, true);

                    int statusCount = 0;
                    messageBus.Subscribe <WorkItemStatus>(status => {
                        _logger.Trace("Progress: {progress}", status.Progress);
                        Assert.Equal(jobId, status.WorkItemId);
                        statusCount++;
                    });

                    await job.RunUntilEmptyAsync();

                    Assert.Equal(12, statusCount);
                }
            }
        }
Example #4
0
        public async Task CanRunWorkItemWithClassHandler()
        {
            using (var queue = new InMemoryQueue <WorkItemData>(new InMemoryQueueOptions <WorkItemData> {
                LoggerFactory = Log
            })) {
                using (var messageBus = new InMemoryMessageBus(new InMemoryMessageBusOptions {
                    LoggerFactory = Log
                })) {
                    var handlerRegistry = new WorkItemHandlers();
                    var job             = new WorkItemJob(queue, messageBus, handlerRegistry, Log);

                    handlerRegistry.Register <MyWorkItem>(new MyWorkItemHandler(Log));

                    string jobId = await queue.EnqueueAsync(new MyWorkItem {
                        SomeData = "Test"
                    }, true);

                    int statusCount = 0;
                    await messageBus.SubscribeAsync <WorkItemStatus>(status => {
                        _logger.Trace("Progress: {progress}", status.Progress);
                        Assert.Equal(jobId, status.WorkItemId);
                        statusCount++;
                    });

                    await job.RunUntilEmptyAsync();

                    Assert.Equal(11, statusCount);
                }
            }
        }
        public void CanRunWorkItemWithClassHandler()
        {
            ServiceProvider.SetServiceProvider(typeof(MyBootstrappedServiceProvider));
            var queue           = new InMemoryQueue <WorkItemData>();
            var messageBus      = new InMemoryMessageBus();
            var handlerRegistry = new WorkItemHandlers();
            var job             = new WorkItemJob(queue, messageBus, handlerRegistry);

            handlerRegistry.Register <MyWorkItem, MyWorkItemHandler>();

            var jobId = queue.Enqueue(new MyWorkItem {
                SomeData = "Test"
            }, true);

            int statusCount = 0;

            messageBus.Subscribe <WorkItemStatus>(status => {
                Assert.Equal(jobId, status.WorkItemId);
                statusCount++;
            });

            job.RunUntilEmpty();

            Assert.Equal(12, statusCount);
        }
Example #6
0
        public async Task CanRunBadWorkItem()
        {
            using (var queue = new InMemoryQueue <WorkItemData>(o => o.RetryDelay(TimeSpan.FromMilliseconds(500)).LoggerFactory(Log))) {
                using (var messageBus = new InMemoryMessageBus(o => o.LoggerFactory(Log))) {
                    var handlerRegistry = new WorkItemHandlers();
                    var job             = new WorkItemJob(queue, messageBus, handlerRegistry, Log);

                    handlerRegistry.Register <MyWorkItem>(ctx => {
                        var jobData = ctx.GetData <MyWorkItem>();
                        Assert.Equal("Test", jobData.SomeData);
                        throw new Exception();
                    });

                    string jobId = await queue.EnqueueAsync(new MyWorkItem {
                        SomeData = "Test"
                    }, true);

                    var countdown = new AsyncCountdownEvent(1);
                    await messageBus.SubscribeAsync <WorkItemStatus>(status => {
                        if (_logger.IsEnabled(LogLevel.Trace))
                        {
                            _logger.LogTrace("Progress: {Progress}", status.Progress);
                        }
                        Assert.Equal(jobId, status.WorkItemId);
                        countdown.Signal();
                    });

                    await job.RunUntilEmptyAsync();

                    await countdown.WaitAsync(TimeSpan.FromSeconds(2));

                    Assert.Equal(0, countdown.CurrentCount);
                }
            }
        }
        public void CanRunWorkItem()
        {
            var queue           = new InMemoryQueue <WorkItemData>();
            var messageBus      = new InMemoryMessageBus();
            var handlerRegistry = new WorkItemHandlers();
            var job             = new WorkItemJob(queue, messageBus, handlerRegistry);

            handlerRegistry.Register <MyWorkItem>(async ctx => {
                var jobData = ctx.GetData <MyWorkItem>();
                Assert.Equal("Test", jobData.SomeData);

                for (int i = 0; i < 10; i++)
                {
                    Thread.Sleep(100);
                    ctx.ReportProgress(10 * i);
                }
            });

            var jobId = queue.Enqueue(new MyWorkItem {
                SomeData = "Test"
            }, true);

            int statusCount = 0;

            messageBus.Subscribe <WorkItemStatus>(status => {
                Assert.Equal(jobId, status.WorkItemId);
                statusCount++;
            });

            job.RunUntilEmpty();

            Assert.Equal(12, statusCount);
        }
Example #8
0
        public async Task CanRunWorkItemWithClassHandler()
        {
            ServiceProvider.SetServiceProvider(typeof(MyBootstrappedServiceProvider));
            var queue           = new InMemoryQueue <WorkItemData>();
            var messageBus      = new InMemoryMessageBus();
            var handlerRegistry = new WorkItemHandlers();
            var job             = new WorkItemJob(queue, messageBus, handlerRegistry, Log);

            handlerRegistry.Register <MyWorkItem, MyWorkItemHandler>();

            var jobId = await queue.EnqueueAsync(new MyWorkItem {
                SomeData = "Test"
            }, true);

            int statusCount = 0;

            messageBus.Subscribe <WorkItemStatus>(status => {
                _logger.Trace("Progress: {progress}", status.Progress);
                Assert.Equal(jobId, status.WorkItemId);
                statusCount++;
            });

            await job.RunUntilEmptyAsync();

            Assert.Equal(11, statusCount);
        }
Example #9
0
        public async Task CanRunBadWorkItem()
        {
            var queue           = new InMemoryQueue <WorkItemData>(retries: 2, retryDelay: TimeSpan.FromMilliseconds(500));
            var messageBus      = new InMemoryMessageBus();
            var handlerRegistry = new WorkItemHandlers();
            var job             = new WorkItemJob(queue, messageBus, handlerRegistry);

            handlerRegistry.Register <MyWorkItem>(ctx => {
                var jobData = ctx.GetData <MyWorkItem>();
                Assert.Equal("Test", jobData.SomeData);
                throw new ApplicationException();
            });

            var jobId = await queue.EnqueueAsync(new MyWorkItem {
                SomeData = "Test"
            }, true);

            int statusCount = 0;

            messageBus.Subscribe <WorkItemStatus>(status => {
                Logger.Trace().Message($"Progress: {status.Progress}").Write();
                Assert.Equal(jobId, status.WorkItemId);
                statusCount++;
            });

            await job.RunUntilEmptyAsync();

            Assert.Equal(1, statusCount);
        }
        public async Task CanRunWorkItemWithDelegateHandler()
        {
            using (var queue = new InMemoryQueue <WorkItemData>(new InMemoryQueueOptions <WorkItemData> {
                LoggerFactory = Log
            })) {
                using (var messageBus = new InMemoryMessageBus(new InMemoryMessageBusOptions {
                    LoggerFactory = Log
                })) {
                    var handlerRegistry = new WorkItemHandlers();
                    var job             = new WorkItemJob(queue, messageBus, handlerRegistry, Log);

                    handlerRegistry.Register <MyWorkItem>(async ctx => {
                        var jobData = ctx.GetData <MyWorkItem>();
                        Assert.Equal("Test", jobData.SomeData);

                        for (int i = 1; i < 10; i++)
                        {
                            await SystemClock.SleepAsync(100);
                            await ctx.ReportProgressAsync(10 * i);
                        }
                    }, Log.CreateLogger("MyWorkItem"));

                    string jobId = await queue.EnqueueAsync(new MyWorkItem {
                        SomeData = "Test"
                    }, true);

                    int statusCount = 0;
                    await messageBus.SubscribeAsync <WorkItemStatus>(status => {
                        if (_logger.IsEnabled(LogLevel.Trace))
                        {
                            _logger.LogTrace("Progress: {Progress}", status.Progress);
                        }
                        Assert.Equal(jobId, status.WorkItemId);
                        Interlocked.Increment(ref statusCount);
                    });

                    await job.RunUntilEmptyAsync();

                    Assert.Equal(11, statusCount);
                }
            }
        }
Example #11
0
        public void CanRunBadWorkItem()
        {
            var queue           = new InMemoryQueue <WorkItemData>();
            var messageBus      = new InMemoryMessageBus();
            var handlerRegistry = new WorkItemHandlers();
            var job             = new WorkItemJob(queue, messageBus, handlerRegistry);

            handlerRegistry.Register <MyWorkItem>(async ctx => {
                var jobData = ctx.GetData <MyWorkItem>();
                Assert.Equal("Test", jobData.SomeData);
                throw new ApplicationException();
            });

            var jobId = queue.Enqueue(new MyWorkItem {
                SomeData = "Test"
            }, true);

            int statusCount = 0;

            messageBus.Subscribe <WorkItemStatus>(status => {
                Assert.Equal(jobId, status.WorkItemId);
                statusCount++;
            });

            job.RunUntilEmpty();

            Assert.Equal(1, statusCount);

            handlerRegistry.Register <MyWorkItem>(async ctx => {
                var jobData = ctx.GetData <MyWorkItem>();
                Assert.Equal("Test", jobData.SomeData);
            });

            jobId = queue.Enqueue(new MyWorkItem {
                SomeData = "Test"
            }, true);

            job.RunUntilEmpty();

            Assert.Equal(2, statusCount);
        }
Example #12
0
        public async Task CanRunWorkItemWithDelegateHandler()
        {
            using (var queue = new InMemoryQueue <WorkItemData>(o => o.LoggerFactory(Log))) {
                using (var messageBus = new InMemoryMessageBus(o => o.LoggerFactory(Log))) {
                    var handlerRegistry = new WorkItemHandlers();
                    var job             = new WorkItemJob(queue, messageBus, handlerRegistry, Log);

                    handlerRegistry.Register <MyWorkItem>(async ctx => {
                        var jobData = ctx.GetData <MyWorkItem>();
                        Assert.Equal("Test", jobData.SomeData);

                        for (int i = 1; i < 10; i++)
                        {
                            await SystemClock.SleepAsync(100);
                            await ctx.ReportProgressAsync(10 * i);
                        }
                    }, Log.CreateLogger("MyWorkItem"));

                    string jobId = await queue.EnqueueAsync(new MyWorkItem {
                        SomeData = "Test"
                    }, true);

                    var countdown = new AsyncCountdownEvent(11);
                    await messageBus.SubscribeAsync <WorkItemStatus>(status => {
                        if (_logger.IsEnabled(LogLevel.Trace))
                        {
                            _logger.LogTrace("Progress: {Progress}", status.Progress);
                        }
                        Assert.Equal(jobId, status.WorkItemId);
                        countdown.Signal();
                    });

                    await job.RunUntilEmptyAsync();

                    await countdown.WaitAsync(TimeSpan.FromSeconds(2));

                    Assert.Equal(0, countdown.CurrentCount);
                }
            }
        }
Example #13
0
        public async Task CanHandleMultipleWorkItemInstances()
        {
            const int workItemCount = 1000;

            using (var metrics = new InMemoryMetricsClient(new InMemoryMetricsClientOptions {
                LoggerFactory = Log
            })) {
                var options = new InMemoryQueueOptions <WorkItemData> {
                    Retries = 0, RetryDelay = TimeSpan.Zero, LoggerFactory = Log
                };
                using (var queue = new InMemoryQueue <WorkItemData>(options)) {
                    queue.AttachBehavior(new MetricsQueueBehavior <WorkItemData>(metrics, loggerFactory: Log));
                    using (var messageBus = new InMemoryMessageBus(new InMemoryMessageBusOptions {
                        LoggerFactory = Log
                    })) {
                        var handlerRegistry = new WorkItemHandlers();
                        var j1     = new WorkItemJob(queue, messageBus, handlerRegistry, Log);
                        var j2     = new WorkItemJob(queue, messageBus, handlerRegistry, Log);
                        var j3     = new WorkItemJob(queue, messageBus, handlerRegistry, Log);
                        int errors = 0;

                        var jobIds = new ConcurrentDictionary <string, int>();

                        handlerRegistry.Register <MyWorkItem>(async ctx => {
                            var jobData = ctx.GetData <MyWorkItem>();
                            Assert.Equal("Test", jobData.SomeData);

                            int jobWorkTotal = jobIds.AddOrUpdate(ctx.JobId, 1, (key, value) => value + 1);
                            if (jobData.Index % 100 == 0)
                            {
                                _logger.Trace("Job {jobId} processing work item #: {jobWorkTotal}", ctx.JobId, jobWorkTotal);
                            }

                            for (int i = 0; i < 10; i++)
                            {
                                await ctx.ReportProgressAsync(10 * i);
                            }

                            if (RandomData.GetBool(1))
                            {
                                Interlocked.Increment(ref errors);
                                throw new Exception("Boom!");
                            }
                        });

                        for (int i = 0; i < workItemCount; i++)
                        {
                            await queue.EnqueueAsync(new MyWorkItem {
                                SomeData = "Test",
                                Index    = i
                            }, true);
                        }

                        var    completedItems     = new List <string>();
                        object completedItemsLock = new object();
                        await messageBus.SubscribeAsync <WorkItemStatus>(status => {
                            if (status.Progress == 100)
                            {
                                _logger.Trace("Progress: {progress}", status.Progress);
                            }

                            if (status.Progress < 100)
                            {
                                return;
                            }

                            lock (completedItemsLock)
                                completedItems.Add(status.WorkItemId);
                        });

                        var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(10));
                        var tasks = new List <Task> {
                            Task.Run(async() => {
                                await j1.RunUntilEmptyAsync(cancellationTokenSource.Token);
                                cancellationTokenSource.Cancel();
                            }, cancellationTokenSource.Token),
                            Task.Run(async() => {
                                await j2.RunUntilEmptyAsync(cancellationTokenSource.Token);
                                cancellationTokenSource.Cancel();
                            }, cancellationTokenSource.Token),
                            Task.Run(async() => {
                                await j3.RunUntilEmptyAsync(cancellationTokenSource.Token);
                                cancellationTokenSource.Cancel();
                            }, cancellationTokenSource.Token)
                        };

                        try {
                            await Task.WhenAll(tasks);
                        } catch (OperationCanceledException ex) {
                            _logger.Error(ex, $"One or more tasks were cancelled: {ex.Message}");
                        }

                        await SystemClock.SleepAsync(100);

                        _logger.Info("Completed: {completedItems} Errors: {errors}", completedItems.Count, errors);
                        Assert.Equal(workItemCount, completedItems.Count + errors);
                        Assert.Equal(3, jobIds.Count);
                        Assert.Equal(workItemCount, jobIds.Sum(kvp => kvp.Value));
                    }
                }
            }
        }
Example #14
0
        public async Task CanHandleMultipleWorkItemInstances()
        {
            const int workItemCount = 1000;

            var metrics = new InMemoryMetricsClient();
            var queue   = new InMemoryQueue <WorkItemData>(retries: 0, retryDelay: TimeSpan.Zero);

            queue.AttachBehavior(new MetricsQueueBehavior <WorkItemData>(metrics));
            var messageBus      = new InMemoryMessageBus();
            var handlerRegistry = new WorkItemHandlers();
            var j1     = new WorkItemJob(queue, messageBus, handlerRegistry);
            var j2     = new WorkItemJob(queue, messageBus, handlerRegistry);
            var j3     = new WorkItemJob(queue, messageBus, handlerRegistry);
            int errors = 0;

            var jobIds = new ConcurrentDictionary <string, int>();

            handlerRegistry.Register <MyWorkItem>(async ctx => {
                var jobData = ctx.GetData <MyWorkItem>();
                Assert.Equal("Test", jobData.SomeData);

                var jobWorkTotal = jobIds.AddOrUpdate(ctx.JobId, 1, (key, value) => value + 1);
                Logger.Trace().Message($"Job {ctx.JobId} processing work item #: {jobWorkTotal}").Write();

                for (int i = 0; i < 10; i++)
                {
                    await ctx.ReportProgressAsync(10 * i);
                }

                if (RandomData.GetBool(1))
                {
                    Interlocked.Increment(ref errors);
                    throw new ApplicationException("Boom!");
                }
            });

            for (int i = 0; i < workItemCount; i++)
            {
                await queue.EnqueueAsync(new MyWorkItem {
                    SomeData = "Test",
                    Index    = i
                }, true);
            }

            var    completedItems     = new List <string>();
            object completedItemsLock = new object();

            messageBus.Subscribe <WorkItemStatus>(status => {
                Logger.Trace().Message($"Progress: {status.Progress}").Write();
                if (status.Progress < 100)
                {
                    return;
                }

                lock (completedItemsLock)
                    completedItems.Add(status.WorkItemId);
            });

            var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(10));
            var tasks = new List <Task> {
                Task.Run(async() => {
                    await j1.RunUntilEmptyAsync(cancellationTokenSource.Token);
                    cancellationTokenSource.Cancel();
                }, cancellationTokenSource.Token),
                Task.Run(async() => {
                    await j2.RunUntilEmptyAsync(cancellationTokenSource.Token);
                    cancellationTokenSource.Cancel();
                }, cancellationTokenSource.Token),
                Task.Run(async() => {
                    await j3.RunUntilEmptyAsync(cancellationTokenSource.Token);
                    cancellationTokenSource.Cancel();
                }, cancellationTokenSource.Token)
            };

            try {
                await Task.WhenAll(tasks);

                await Task.Delay(100);
            } catch (TaskCanceledException) {}

            Logger.Info().Message($"Completed: {completedItems.Count} Errors: {errors}").Write();
            metrics.DisplayStats(_writer);

            Assert.Equal(workItemCount, completedItems.Count + errors);
            Assert.Equal(3, jobIds.Count);
            Assert.Equal(workItemCount, jobIds.Sum(kvp => kvp.Value));
        }