83 lines
3.6 KiB
C#
83 lines
3.6 KiB
C#
using System;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using MediaBrowser.Common.Configuration;
|
|
using MediaBrowser.Controller.Entities;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace Emby.Server.Implementations.Configuration
|
|
{
|
|
/// <summary>
|
|
/// Applies the configuration invalidations published by the other instances sharing this
|
|
/// configuration directory, dropping the local cache entry so the next read comes off the shared file.
|
|
/// </summary>
|
|
public sealed class ConfigurationInvalidationSubscriber : IHostedService
|
|
{
|
|
private readonly IConfigurationInvalidationBus _bus;
|
|
private readonly IConfigurationManager _configurationManager;
|
|
private readonly ILogger<ConfigurationInvalidationSubscriber> _logger;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="ConfigurationInvalidationSubscriber"/> class.
|
|
/// </summary>
|
|
/// <param name="bus">The invalidation bus.</param>
|
|
/// <param name="configurationManager">The configuration manager holding the cached configuration.</param>
|
|
/// <param name="logger">The logger.</param>
|
|
public ConfigurationInvalidationSubscriber(
|
|
IConfigurationInvalidationBus bus,
|
|
IConfigurationManager configurationManager,
|
|
ILogger<ConfigurationInvalidationSubscriber> logger)
|
|
{
|
|
_bus = bus;
|
|
_configurationManager = configurationManager;
|
|
_logger = logger;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public Task StartAsync(CancellationToken cancellationToken)
|
|
{
|
|
_bus.Subscribe(Apply);
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
|
|
|
private void Apply(ConfigurationInvalidation invalidation)
|
|
{
|
|
try
|
|
{
|
|
// Applying re-raises the same update events a local save raises, so the in-process
|
|
// consumers re-read. The scope tells those consumers that the write was somebody else's,
|
|
// so the ones that answer an update by writing neither repeat it nor publish it back.
|
|
using var scope = ConfigurationInvalidationContext.BeginApply();
|
|
|
|
switch (invalidation.Scope)
|
|
{
|
|
case ConfigurationInvalidationScope.SystemConfiguration:
|
|
_configurationManager.InvalidateCachedConfiguration(null);
|
|
break;
|
|
case ConfigurationInvalidationScope.NamedConfiguration when !string.IsNullOrEmpty(invalidation.Target):
|
|
_configurationManager.InvalidateCachedConfiguration(invalidation.Target);
|
|
break;
|
|
case ConfigurationInvalidationScope.LibraryOptions when !string.IsNullOrEmpty(invalidation.Target):
|
|
CollectionFolder.InvalidateLibraryOptions(invalidation.Target);
|
|
break;
|
|
case ConfigurationInvalidationScope.AllLibraryOptions:
|
|
CollectionFolder.InvalidateAllLibraryOptions();
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
_logger.LogDebug("Applied {Scope} invalidation for {Target} from {OriginId}.", invalidation.Scope, invalidation.Target, invalidation.OriginId);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogWarning(ex, "Failed to apply a {Scope} invalidation for {Target}.", invalidation.Scope, invalidation.Target);
|
|
}
|
|
}
|
|
}
|
|
}
|