Fix SessionManager._activeLiveStreamSessions for HA pod takeover safety (#27)
* Initial plan * Issue 5.2.3b: Fix SessionManager._activeLiveStreamSessions for takeover safety Co-authored-by: ZoltyMat <177592743+ZoltyMat@users.noreply.github.com> * ci: trigger CI run for PR #27 review --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: ZoltyMat <177592743+ZoltyMat@users.noreply.github.com> Co-authored-by: mat <mstrommen@gmail.com>
This commit is contained in:
@@ -70,4 +70,35 @@ public interface ITranscodeSessionStore
|
||||
/// Returns an empty enumerable if no sessions are active or if the store cannot be reached.
|
||||
/// </returns>
|
||||
Task<IEnumerable<TranscodeSession>> GetActiveSessionsAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Persists a live stream session record so that takeover pods can identify and close
|
||||
/// streams that were opened on a pod that has since crashed or been evicted.
|
||||
/// </summary>
|
||||
/// <param name="session">The live stream session to store.</param>
|
||||
/// <param name="cancellationToken">A cancellation token.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
Task SetLiveStreamAsync(LiveStreamSession session, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to retrieve a live stream session by its live stream identifier and the
|
||||
/// session or play-session identifier that owns it.
|
||||
/// </summary>
|
||||
/// <param name="liveStreamId">The live stream identifier.</param>
|
||||
/// <param name="sessionIdOrPlaySessionId">The session identifier or play-session identifier.</param>
|
||||
/// <param name="cancellationToken">A cancellation token.</param>
|
||||
/// <returns>
|
||||
/// The <see cref="LiveStreamSession"/> if it exists; otherwise <c>null</c>.
|
||||
/// </returns>
|
||||
Task<LiveStreamSession?> TryGetLiveStreamAsync(string liveStreamId, string sessionIdOrPlaySessionId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the live stream session record for the given live stream and session identifier.
|
||||
/// This is called when the stream is closed, either by the owning pod or a takeover pod.
|
||||
/// </summary>
|
||||
/// <param name="liveStreamId">The live stream identifier.</param>
|
||||
/// <param name="sessionIdOrPlaySessionId">The session identifier or play-session identifier.</param>
|
||||
/// <param name="cancellationToken">A cancellation token.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
Task DeleteLiveStreamAsync(string liveStreamId, string sessionIdOrPlaySessionId, CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Controller.MediaEncoding;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a durable record of an open live stream session, enabling HA pod recovery
|
||||
/// when the owning pod crashes or is evicted.
|
||||
/// </summary>
|
||||
public sealed class LiveStreamSession
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the live stream identifier (e.g. a TV tuner channel token).
|
||||
/// </summary>
|
||||
public string LiveStreamId { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the session identifier of the client that opened this live stream.
|
||||
/// </summary>
|
||||
public string SessionId { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the play session identifier associated with this live stream,
|
||||
/// or an empty string when the client did not supply one.
|
||||
/// </summary>
|
||||
public string PlaySessionId { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the pod that currently holds this live stream open.
|
||||
/// </summary>
|
||||
public string OwnerPod { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the UTC time at which this record was created.
|
||||
/// </summary>
|
||||
public DateTime OpenedAtUtc { get; set; }
|
||||
}
|
||||
@@ -34,4 +34,16 @@ public sealed class NullTranscodeSessionStore : ITranscodeSessionStore
|
||||
/// <inheritdoc />
|
||||
public Task<IEnumerable<TranscodeSession>> GetActiveSessionsAsync(CancellationToken cancellationToken = default)
|
||||
=> Task.FromResult<IEnumerable<TranscodeSession>>(Array.Empty<TranscodeSession>());
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task SetLiveStreamAsync(LiveStreamSession session, CancellationToken cancellationToken = default)
|
||||
=> Task.CompletedTask;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<LiveStreamSession?> TryGetLiveStreamAsync(string liveStreamId, string sessionIdOrPlaySessionId, CancellationToken cancellationToken = default)
|
||||
=> Task.FromResult<LiveStreamSession?>(null);
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task DeleteLiveStreamAsync(string liveStreamId, string sessionIdOrPlaySessionId, CancellationToken cancellationToken = default)
|
||||
=> Task.CompletedTask;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user