DD.WellWorkover.Cloud/AsbCloudWebApi/SignalR/Services/SignalRNotificationTransportService.cs

56 lines
1.9 KiB
C#

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<NotificationDto> 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<string, IServiceProvider, Action<string, double?>, CancellationToken, Task> MakeSignalRSendWorkAction(IEnumerable<NotificationDto> notifications)
{
return async (_, serviceProvider, onProgress, cancellationToken) =>
{
var notificationPublisher = serviceProvider.GetRequiredService<NotificationPublisher>();
var groupedNotificationsByUsers = notifications.GroupBy(n => n.IdUser);
foreach (var groupedNotificationByUser in groupedNotificationsByUsers)
{
await notificationPublisher.PublishAsync(groupedNotificationByUser, cancellationToken);
}
};
}
}