Files
ersatztv/ErsatzTV.Core/Streaming/DirectStreamSessionTracker.cs
T
2026-07-04 19:57:50 +02:00

65 lines
2.2 KiB
C#

using System.Collections.Concurrent;
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Streaming;
namespace ErsatzTV.Core.Streaming;
public class DirectStreamSessionTracker : IDirectStreamSessionTracker
{
private readonly ConcurrentDictionary<string, ConcurrentDictionary<Guid, DirectStreamSession>> _sessions = new();
public IDisposable Register(string channelNumber, StreamingMode streamingMode)
{
var session = new DirectStreamSession(Guid.NewGuid(), channelNumber, streamingMode, DateTimeOffset.Now);
ConcurrentDictionary<Guid, DirectStreamSession> channelSessions =
_sessions.GetOrAdd(channelNumber, _ => new ConcurrentDictionary<Guid, DirectStreamSession>());
channelSessions.TryAdd(session.Id, session);
return new Registration(this, session);
}
public bool IsActive(string channelNumber) => GetViewerCount(channelNumber) > 0;
public int GetViewerCount(string channelNumber) =>
_sessions.TryGetValue(channelNumber, out ConcurrentDictionary<Guid, DirectStreamSession> channelSessions)
? channelSessions.Count
: 0;
public IReadOnlyCollection<DirectStreamSession> GetActiveSessions() =>
_sessions.Values.SelectMany(s => s.Values).ToList();
public IReadOnlyCollection<DirectStreamSession> GetActiveSessions(string channelNumber) =>
_sessions.TryGetValue(channelNumber, out ConcurrentDictionary<Guid, DirectStreamSession> channelSessions)
? channelSessions.Values.ToList()
: [];
private void Remove(DirectStreamSession session)
{
if (!_sessions.TryGetValue(session.ChannelNumber, out ConcurrentDictionary<Guid, DirectStreamSession> channelSessions))
{
return;
}
channelSessions.TryRemove(session.Id, out _);
if (channelSessions.IsEmpty)
{
_sessions.TryRemove(session.ChannelNumber, out _);
}
}
private sealed class Registration(DirectStreamSessionTracker tracker, DirectStreamSession session) : IDisposable
{
private int _disposed;
public void Dispose()
{
if (Interlocked.Exchange(ref _disposed, 1) == 0)
{
tracker.Remove(session);
}
}
}
}