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); } }