using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using AsbCloudApp.Data; using AsbCloudApp.Services.Notifications; using AsbCloudInfrastructure.Background; using Microsoft.Extensions.DependencyInjection; namespace AsbCloudWebApi.SignalR.Services; public class SignalRNotificationTransportService : INotificationTransportService { private readonly NotificationBackgroundWorker backgroundWorker; public SignalRNotificationTransportService(NotificationBackgroundWorker backgroundWorker) { this.backgroundWorker = backgroundWorker; } public int IdTransportType => 0; public Task SendAsync(NotificationDto notification, CancellationToken cancellationToken) => SendRangeAsync(new[] { notification }, cancellationToken); public Task SendRangeAsync(IEnumerable notifications, CancellationToken cancellationToken) { var workId = HashCode.Combine(notifications.Select(n => n.Id)).ToString("x"); if (backgroundWorker.Works.Any(w => w.Id == workId)) return Task.CompletedTask; var workAction = MakeSignalRSendWorkAction(notifications); var work = Work.CreateByDelegate(workId, workAction); backgroundWorker.Enqueue(work); return Task.CompletedTask; } private Func, CancellationToken, Task> MakeSignalRSendWorkAction(IEnumerable notifications) { return async (_, serviceProvider, onProgress, cancellationToken) => { var notificationPublisher = serviceProvider.GetRequiredService(); var groupedNotificationsByUsers = notifications.GroupBy(n => n.IdUser); foreach (var groupedNotificationByUser in groupedNotificationsByUsers) { await notificationPublisher.PublishAsync(groupedNotificationByUser, cancellationToken); } }; } }