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; /// /// 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. /// /// /// This reports, it does not gate. 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. /// public sealed class TranscodeStoreConnectivityProbe : IHostedService { private readonly IServiceProvider _serviceProvider; private readonly ILogger _logger; /// /// Initializes a new instance of the class. /// /// The service provider used to resolve the Redis connection. /// The logger. public TranscodeStoreConnectivityProbe(IServiceProvider serviceProvider, ILogger logger) { _serviceProvider = serviceProvider; _logger = logger; } /// 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(); 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); } } /// public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; }