Creado apartir del commit b888de6c92056de294456f581a56e25e734d4ab7 de develop
This commit is contained in:
@@ -0,0 +1,224 @@
|
||||
using adas_core.Application.Services.Interfaces;
|
||||
using adas_core.Domain.Enums;
|
||||
using adas_core.Domain.Models;
|
||||
using adas_core.Domain.Models.GroupedObservations;
|
||||
using adas_core.Domain.Utils;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MongoDB.Bson;
|
||||
|
||||
namespace adas_core.Application.Subscriptions;
|
||||
|
||||
public class SubscriberGroupedService(
|
||||
ICacheService? cacheService,
|
||||
IGroupedObservationService groupedObservationService,
|
||||
ILogger<SubscriberGroupedService> logger,
|
||||
Lazy<IClientMessageService> clientMessageService)
|
||||
: ISubscriberGroupedService
|
||||
{
|
||||
private List<WsSubscriberGrouped> _subscriberGrouped = [];
|
||||
|
||||
|
||||
//private static readonly ILogger _logger = Log.ForContext<SubscriberGrouped>();
|
||||
|
||||
public List<WsSubscriberGrouped> SubscriberGroupedList
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_subscriberGrouped)
|
||||
{
|
||||
return _subscriberGrouped;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
lock (_subscriberGrouped)
|
||||
{
|
||||
_subscriberGrouped = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<WsSubscriberGrouped> GetGrouped()
|
||||
{
|
||||
lock (_subscriberGrouped)
|
||||
{
|
||||
return _subscriberGrouped.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveGroupedObsByPatientId(string patientId)
|
||||
{
|
||||
lock (_subscriberGrouped)
|
||||
{
|
||||
var itemToRemove = _subscriberGrouped.Where(c => c.PatientId.ToString() == patientId).ToList();
|
||||
itemToRemove.ForEach(item => _subscriberGrouped.Remove(item));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if what clients dont need to get updated with new grouped observations and remove them
|
||||
/// diference between section and box if location is updated doesn't matter if is section or box
|
||||
/// BoxSubscribers don't need to get updated otherwise SectionSubscribers may still need to get updated
|
||||
/// </summary>
|
||||
/// <param name="patientId">objectId on db for Patient</param>
|
||||
/// <param name="newLocation"></param>
|
||||
public void RemoveWsSubscriberByLocation(string patientId, PatientLocation? newLocation)
|
||||
{
|
||||
lock (_subscriberGrouped)
|
||||
{
|
||||
var itemToRemove = _subscriberGrouped.Where(c => c.PatientId.ToString() == patientId).ToList();
|
||||
foreach (var wsSubscriberGrouped in itemToRemove)
|
||||
{
|
||||
// Make a separate list for wsClients to be removed
|
||||
var wsClientsToRemove = new List<string>();
|
||||
foreach (var wsClient in wsSubscriberGrouped.WsSubscriber) wsClientsToRemove.Add(wsClient);
|
||||
|
||||
// Remove the wsClients
|
||||
foreach (var wsClient in wsClientsToRemove) wsSubscriberGrouped.WsSubscriber.Remove(wsClient);
|
||||
|
||||
CheckEmptySubscriberGroup(wsSubscriberGrouped);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveWsSubscriberPatientIdAndWsId(string patientId, string wsIdToRemove)
|
||||
{
|
||||
lock (_subscriberGrouped)
|
||||
{
|
||||
var itemToRemove = _subscriberGrouped
|
||||
.Where(c => c.PatientId.ToString() == patientId && c.WsSubscriber.Contains(wsIdToRemove)).ToList();
|
||||
foreach (var wsSubscriberGrouped in itemToRemove)
|
||||
{
|
||||
// // Make a separate list for wsClients to be removed
|
||||
// var wsClientsToRemove = new List<string>();
|
||||
// foreach (var wsClient in wsSubscriberGrouped.WsSubscriber)
|
||||
// {
|
||||
// if(wsClient == wsIdToRemove)
|
||||
// wsClientsToRemove.Add(wsClient);
|
||||
// }
|
||||
//
|
||||
// // Remove the wsClients
|
||||
// foreach (var wsClient in wsClientsToRemove)
|
||||
// {
|
||||
// wsSubscriberGrouped.WsSubscriber.Remove(wsClient);
|
||||
// wsSubscriberGrouped.Group.Remove(wsClient);
|
||||
// }
|
||||
wsSubscriberGrouped.WsSubscriber.Remove(wsIdToRemove);
|
||||
wsSubscriberGrouped.Group.Remove(wsIdToRemove);
|
||||
|
||||
CheckEmptySubscriberGroup(wsSubscriberGrouped);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check clients using generated grouped observations on disconections
|
||||
/// removing the wole object in case of 0 or
|
||||
/// only the group if any other client is using it
|
||||
/// </summary>
|
||||
/// <param name="wsSubscriberGrouped">
|
||||
/// Object with properties to generate new grouped observations, clients using those
|
||||
/// grouped obsercations and the generated list of grouped observations
|
||||
/// </param>
|
||||
public List<string> CheckEmptySubscriberGroup(WsSubscriberGrouped? wsSubscriberGrouped)
|
||||
{
|
||||
lock (_subscriberGrouped)
|
||||
{
|
||||
var removed = new List<string>();
|
||||
if (wsSubscriberGrouped == null) return [];
|
||||
|
||||
if (wsSubscriberGrouped.WsSubscriber.Count == 0)
|
||||
{
|
||||
//_logger.Debug($"Removing wsSubscriberGrouped from list because client subscriber are empty");
|
||||
wsSubscriberGrouped.Timer.Stop();
|
||||
wsSubscriberGrouped.Timer.Dispose();
|
||||
_subscriberGrouped.Remove(wsSubscriberGrouped);
|
||||
removed.Add(
|
||||
$"ws:{wsSubscriberGrouped.PatientId}-{string.Join(";", wsSubscriberGrouped.Names)}-{wsSubscriberGrouped.Regularity}-{wsSubscriberGrouped.Group.Count}");
|
||||
cacheService?.DeleteObjectAsync(wsSubscriberGrouped.HashCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var kvp in wsSubscriberGrouped.Group.ToList())
|
||||
if (!wsSubscriberGrouped.WsSubscriber.Any(subscriber =>
|
||||
subscriber.Contains(kvp.Key)))
|
||||
{
|
||||
//_logger.Debug($"Removing group {kvp.Key}:{kvp.Value} from list because client subscriber got disconnected but wsSubscriberGrouped still in use with {wsSubscriberGrouped.WsSubscriber.Count()} clients");
|
||||
wsSubscriberGrouped.Group.Remove(kvp.Key);
|
||||
wsSubscriberGrouped.WsSubscriber.Remove(kvp.Key);
|
||||
removed.Add($"group:{kvp.Key}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return removed;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddSubscriberGrouped(WsSubscriberGrouped wsSubscriberGrouped)
|
||||
{
|
||||
lock (_subscriberGrouped)
|
||||
{
|
||||
_subscriberGrouped.Add(wsSubscriberGrouped);
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckOnSubscriptionGroup(GroupedField groupedField, ObjectId patientId, string? timeZoneId,
|
||||
string connectionId, GroupedObservation lastObsInGroup)
|
||||
{
|
||||
var wsSubscriberGrouped = GetGrouped().FirstOrDefault(s => s.Compare(groupedField, patientId));
|
||||
if (wsSubscriberGrouped != null)
|
||||
{
|
||||
wsSubscriberGrouped.WsSubscriber.Add(connectionId);
|
||||
|
||||
// Verifica si el diccionario contiene la clave y el valor deseado
|
||||
if (!wsSubscriberGrouped.Group.ContainsKey(connectionId) ||
|
||||
wsSubscriberGrouped.Group[connectionId] != connectionId)
|
||||
// Añade el par clave-valor al diccionario
|
||||
wsSubscriberGrouped.Group[connectionId] = groupedField.Group ?? string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
AddSubscriberGrouped(
|
||||
// ReSharper disable once AsyncVoidLambda
|
||||
new WsSubscriberGrouped(patientId, connectionId, timeZoneId, groupedField, lastObsInGroup,
|
||||
async delegate(object? sender, string _)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (sender is WsSubscriberGrouped ws) await AddEmptyObs(ws);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "Ocurrió un error al procesar el evento del suscriptor.");
|
||||
throw;
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateLastGroupedObsInGroup(string wsgHashCode, GroupedObservation newGroupedObservation)
|
||||
{
|
||||
lock (_subscriberGrouped)
|
||||
{
|
||||
_subscriberGrouped.FirstOrDefault(c => c.HashCode == wsgHashCode)?.UpdateLastGo(newGroupedObservation);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task AddEmptyObs(WsSubscriberGrouped ws)
|
||||
{
|
||||
var gobs = await groupedObservationService.CreateNextEmptyObs(ws);
|
||||
|
||||
UpdateLastGroupedObsInGroup(ws.HashCode, gobs);
|
||||
lock (_subscriberGrouped)
|
||||
{
|
||||
foreach (var sub in ws.WsSubscriber)
|
||||
{
|
||||
gobs.Group = ws.Group.GetValue(sub)!;
|
||||
logger.LogInformation("Sending empty obs on gruped for: {Sub}, with group: {Group}", sub, gobs.Group);
|
||||
|
||||
_ = clientMessageService.Value.SendAsync(sub, OperationType.GroupedObservation, gobs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user