Files
jellyfin-ha-src/Emby.Server.Implementations/MediaEncoding/TranscodeStoreConnectivityProbe.cs
T
unkin-agent 95220e2ed6
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
fix(ha): read transcode store config from the variable form deployments set
The startup configuration only reads JELLYFIN_ prefixed environment
variables, so the bare Jellyfin__TranscodeStore__* form used by the chart,
the manifests and the README is dropped and the Redis store is never
registered. Nothing logs the selected store, so the fallback is invisible.

- Read bare Jellyfin__* variables into the Jellyfin:* configuration root
- Keep an explicit JELLYFIN_ variable winning over the bare form
- Log the selected transcode session store at startup
- Ping Redis once at startup and log an unreachable store at Error
- Log endpoints only, never the connection string
2026-09-13 13:10:52 +10:00

57 lines
2.3 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>
/// Pings the configured Redis transcode session store once at startup so an unreachable store is
/// reported there instead of being discovered as a silent loss of cross-pod takeover.
/// </summary>
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: connecting must not be able to abort startup.
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;
}