using System;
using System.Threading;
namespace MediaBrowser.Common.Configuration
{
///
/// Marks the flow of control that is applying an invalidation published by another instance, so the
/// reactions to it can tell a remote write apart from a local one.
///
///
/// Applying an invalidation raises the same update events a local save raises, because the in-process
/// consumers have to re-read the configuration either way. Some of those consumers answer an update by
/// writing, and that write must neither repeat what the publishing instance already did nor fan back
/// out over the bus. The flag rides the execution context, so it reaches the queued and asynchronous
/// event handlers as well as the synchronous ones.
///
public static class ConfigurationInvalidationContext
{
private static readonly AsyncLocal _applyingRemoteInvalidation = new();
///
/// Gets a value indicating whether the current flow of control is applying an invalidation
/// published by another instance rather than handling a local save.
///
public static bool IsApplyingRemoteInvalidation => _applyingRemoteInvalidation.Value;
///
/// Marks the current flow of control as applying a remote invalidation until the returned scope is
/// disposed.
///
/// The scope to dispose once the invalidation has been applied.
public static IDisposable BeginApply() => new ApplyScope();
private sealed class ApplyScope : IDisposable
{
private readonly bool _previous;
private bool _disposed;
public ApplyScope()
{
_previous = _applyingRemoteInvalidation.Value;
_applyingRemoteInvalidation.Value = true;
}
public void Dispose()
{
if (_disposed)
{
return;
}
_disposed = true;
_applyingRemoteInvalidation.Value = _previous;
}
}
}
}