Files
jellyfin-ha-src/Emby.Server.Implementations/MediaEncoding/TranscodeStoreConnectivityProbe.cs
T
unkin-agent 6c7f76fd26
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
retry the quick connect startup probe, and exit non-zero when a start fails
2026-09-26 22:14:14 +10:00

62 lines
2.6 KiB
C#

using System;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.MediaEncoding;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using StackExchange.Redis;
namespace Emby.Server.Implementations.MediaEncoding;
/// <summary>
/// Reports the round trip to the configured Redis transcode session store once at startup, so the
/// state of cross-pod takeover is visible where the server is started.
/// </summary>
/// <remarks>
/// This reports, it does not gate. <see cref="ApplicationHost.InitializeServices"/> has already read the
/// same connection for quick connect by the time this runs and has stopped startup if it could not be
/// reached, so the error branch here only covers a store that went away in between.
/// </remarks>
public sealed class TranscodeStoreConnectivityProbe : IHostedService
{
private readonly IServiceProvider _serviceProvider;
private readonly ILogger<TranscodeStoreConnectivityProbe> _logger;
/// <summary>
/// Initializes a new instance of the <see cref="TranscodeStoreConnectivityProbe"/> class.
/// </summary>
/// <param name="serviceProvider">The service provider used to resolve the Redis connection.</param>
/// <param name="logger">The logger.</param>
public TranscodeStoreConnectivityProbe(IServiceProvider serviceProvider, ILogger<TranscodeStoreConnectivityProbe> logger)
{
_serviceProvider = serviceProvider;
_logger = logger;
}
/// <inheritdoc />
public async Task StartAsync(CancellationToken cancellationToken)
{
try
{
// Resolved here rather than injected so a store lost after the quick connect gate is reported.
var redis = _serviceProvider.GetRequiredService<IConnectionMultiplexer>();
var roundTrip = await redis.GetDatabase().PingAsync().ConfigureAwait(false);
_logger.LogInformation(
"Redis transcode session store is reachable ({RoundTripMs}ms round trip). HA transcode takeover is active.",
(long)roundTrip.TotalMilliseconds);
}
catch (Exception ex)
{
_logger.LogError(
ex,
"Redis transcode session store is configured but UNREACHABLE. HA transcode takeover is not working: sessions stay local to this instance and are lost when it restarts. Check {Key}.",
TranscodeStoreOptions.RedisConnectionStringKey);
}
}
/// <inheritdoc />
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}