public async Task HandleAsync(ProcessBufferedNotificationsJob job, CancellationToken cancellationToken) { foreach (IBufferGovernor bufferGovernor in bufferGovernors) { MultiValueDictionary <NotificationBuffer, BufferedNotification> toRelease = await bufferGovernor .SelectNotificationsForReleaseAsync(crudRepository); var byPipeline = toRelease.GroupBy(x => x.Key.PipelineId); foreach (var pipelineNotifications in byPipeline) { INotificationPipeline pipeline = notificationPipelines.FirstOrDefault(x => x.Id == pipelineNotifications.Key); if (pipeline == null) { throw new InvalidOperationException( $"Notification pipeline not found: {pipelineNotifications.Key}"); } IReadOnlyCollection <INotification> notifications = pipelineNotifications .SelectMany(x => x.Value) .Select( x => notificationSerializer.FromJson(new SerializedNotification() { NotificationJson = x.NotificationJson, NotificationClassName = x.NotificationClassName })) .ToArray(); await pipeline.ProcessNotificationsAsync(notifications); foreach (BufferedNotification buffNotification in pipelineNotifications.SelectMany(x => x.Value)) { crudRepository.Remove(buffNotification); } await crudRepository.SaveChangesAsync(); } } DateTimeOffset scheduledTime = job.ScheduledTime + TimeSpan.FromMinutes(1); if (scheduledTime <= Clock.Current.Now) { await inMemoryJobScheduler.EnqeueJobAsync(new ProcessBufferedNotificationsJob(Clock.Current.Now), null); } else { await inMemoryJobScheduler.ScheduleJobAsync(new ProcessBufferedNotificationsJob(scheduledTime), scheduledTime); } }
public async Task Run() { try { foreach (IBufferGovernor bufferGovernor in bufferGovernors) { MultiValueDictionary <NotificationBuffer, BufferedNotification> toRelease = await bufferGovernor .SelectNotificationsForReleaseAsync(crudRepository); foreach (var bufferPair in toRelease) { INotificationPipeline pipeline = notificationPipelines.FirstOrDefault(x => x.Id == bufferPair.Key.PipelineId); if (pipeline == null) { throw new InvalidOperationException( $"Notification pipeline not found: {bufferPair.Key.PipelineId}"); } IEnumerable <INotification> notifications = bufferPair.Value .Select( x => notificationSerializer.FromJson(new SerializedNotification() { NotificationJson = x.NotificationJson, NotificationClassName = x.NotificationClassName })); await pipeline.ProcessNotificationsAsync(notifications); foreach (BufferedNotification buffNotification in bufferPair.Value) { crudRepository.Remove(buffNotification); } } } } finally { await crudRepository.SaveChangesAsync(); } }
public BufferedNotificationProcessJobTests() { bufferGovernor1 = Substitute.For <IBufferGovernor>(); bufferGovernor1.Id.Returns(Guid.NewGuid()); inMemoryCrudRepository = new InMemoryCrudRepository(); notificationSerializer = Substitute.For <INotificationSerializer>(); notificationPipeline1 = Substitute.For <INotificationPipeline>(); notificationPipeline1.Id.Returns(Guid.NewGuid()); notificationPipeline2 = Substitute.For <INotificationPipeline>(); notificationPipeline2.Id.Returns(Guid.NewGuid()); notificationSerializer.FromJson(null).ReturnsForAnyArgs(ci => new TestNotification() { Data = ci.ArgAt <SerializedNotification>(0).NotificationJson, TypeName = ci.ArgAt <SerializedNotification>(0).NotificationClassName }); sut = new BufferedNotificationProcessJob(new[] { bufferGovernor1 }, inMemoryCrudRepository, new[] { notificationPipeline1, notificationPipeline2 }, notificationSerializer); }