using System.Collections.Concurrent; namespace SameBeat.Api.Monitoring; /// /// Prosty licznik otwartych polaczen SignalR, trzymany w pamieci procesu (ETAP 8). Wystarczajacy dla /// MVP jednej instancji backendu -- NIE jest to licznik rozproszony: przy kilku instancjach API za /// load balancerem kazda miaƂaby wlasny, czesciowy stan. Rozproszony licznik (np. przez Redis) jest /// poza zakresem MVP. /// /// Kazde polaczenie SignalR trafia od razu do grupy "widzowie" w StanImprezyHub.OnConnectedAsync i -- /// na dzien dzisiejszy -- nigdy z niej nie jest usuwane, wiec licznik ogolny pokrywa sie z licznikiem /// widzow. Grupa "host" jest podzbiorem: polaczenie dolacza do niej wylacznie przez wywolanie /// DolaczDoGrupyHosta (po pozytywnej autoryzacji [Authorize] na tej metodzie). /// /// Watkowo bezpieczne dzieki ConcurrentDictionary -- SignalR moze wywolywac OnConnectedAsync/ /// OnDisconnectedAsync dla wielu polaczen rownolegle. /// public sealed class LicznikPolaczenSignalR { private readonly ConcurrentDictionary _polaczenia = new(); private readonly ConcurrentDictionary _polaczeniaHost = new(); /// Rejestruje nowe polaczenie (kazde polaczenie automatycznie trafia do grupy "widzowie"). public void Polaczono(string idPolaczenia) => _polaczenia[idPolaczenia] = 0; /// Rejestruje dolaczenie polaczenia do grupy "host" (po autoryzacji hosta). public void DolaczylDoGrupyHosta(string idPolaczenia) => _polaczeniaHost[idPolaczenia] = 0; /// Usuwa polaczenie ze wszystkich sledzonych grup -- wywolywane przy rozlaczeniu. public void Rozlaczono(string idPolaczenia) { _polaczenia.TryRemove(idPolaczenia, out _); _polaczeniaHost.TryRemove(idPolaczenia, out _); } /// Liczba wszystkich aktualnie otwartych polaczen SignalR (uzywane w /api/health). public int LiczbaPolaczenOgolem => _polaczenia.Count; /// Liczba polaczen w grupie "widzowie" -- dzis rowna liczbie ogolem, patrz komentarz klasy. public int LiczbaPolaczenWidzowie => _polaczenia.Count; /// Liczba polaczen w grupie "host". public int LiczbaPolaczenHost => _polaczeniaHost.Count; }