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); } } }
public async Task CanHandleMultipleWorkItemInstances() { var metrics = new InMemoryMetricsClient(); var queue = new InMemoryQueue<WorkItemData>(retryDelay: TimeSpan.Zero, retries: 0); 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>(ctx => { var jobData = ctx.GetData<MyWorkItem>(); Assert.Equal("Test", jobData.SomeData); jobIds.AddOrUpdate(ctx.JobId, 1, (key, value) => value + 1); for (int i = 0; i < 10; i++) ctx.ReportProgress(10 * i); if (RandomData.GetBool(1)) { Interlocked.Increment(ref errors); throw new ApplicationException("Boom!"); } return TaskHelper.Completed(); }); for (int i = 0; i < 100; i++) queue.Enqueue(new MyWorkItem { SomeData = "Test", Index = i }, true); var completedItems = new List<string>(); object completedItemsLock = new object(); messageBus.Subscribe<WorkItemStatus>(status => { if (status.Progress < 100) return; lock (completedItemsLock) completedItems.Add(status.WorkItemId); }); var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(10)); var token = cancellationTokenSource.Token; var tasks = new List<Task>(); tasks.AddRange(new[] { Task.Run(async () => await j1.RunUntilEmptyAsync(token), token), Task.Run(async () => await j2.RunUntilEmptyAsync(token), token), Task.Run(async () => await j3.RunUntilEmptyAsync(token), token), }); await Task.WhenAll(tasks); Thread.Sleep(10); Assert.Equal(100, completedItems.Count + errors); Assert.Equal(3, jobIds.Count); Assert.Equal(100, jobIds.Sum(kvp => kvp.Value)); }
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++) { await Task.Delay(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); }
public ElasticRepositoryTestBase(ITestOutputHelper output) : base(output) { SystemClock.Reset(); Log.MinimumLevel = LogLevel.Trace; Log.SetLogLevel<ScheduledTimer>(LogLevel.Warning); _cache = new InMemoryCacheClient(Log); _messgeBus = new InMemoryMessageBus(Log); _workItemQueue = new InMemoryQueue<WorkItemData>(loggerFactory: Log); _configuration = new MyAppElasticConfiguration(_workItemQueue, _cache, _messgeBus, Log); _client = _configuration.Client; }
public async Task CanHandleMultipleWorkItemInstances() { const int workItemCount = 1000; using (var metrics = new InMemoryMetricsClient(loggerFactory: Log)) { using (var queue = new InMemoryQueue<WorkItemData>(retries: 0, retryDelay: TimeSpan.Zero, loggerFactory: Log)) { queue.AttachBehavior(new MetricsQueueBehavior<WorkItemData>(metrics, loggerFactory: Log)); using (var messageBus = new InMemoryMessageBus(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); var 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(); messageBus.Subscribe<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); await SystemClock.SleepAsync(100); } catch (TaskCanceledException) {} _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)); } } } }
public async Task CanRunBadWorkItem() { using (var queue = new InMemoryQueue<WorkItemData>(retries: 2, retryDelay: TimeSpan.FromMilliseconds(500))) { using (var messageBus = new InMemoryMessageBus()) { 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(); }); 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(1, statusCount); } } }
public async Task CanRunWorkItemWithClassHandler() { 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>(new MyWorkItemHandler(Log)); 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); } } }
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); handlerRegistry.Register<MyWorkItem, MyWorkItemHandler>(); 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(11, statusCount); }
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>(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(); Thread.Sleep(1); Assert.Equal(1, statusCount); handlerRegistry.Register<MyWorkItem>(ctx => { var jobData = ctx.GetData<MyWorkItem>(); Assert.Equal("Test", jobData.SomeData); return TaskHelper.Completed(); }); jobId = queue.Enqueue(new MyWorkItem { SomeData = "Test" }, true); job.RunUntilEmpty(); Assert.Equal(2, 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); }