namespace ErsatzTV.Core.Metadata; // #484: the narrow seam that carries "how many items did the server return that we silently dropped // because their projection threw?" out of a media-server API client and back to the scanner that owns // the reconciliation sweep. // // Lifetime is deliberately PER ENUMERATION: the scanner that is about to run a sweep creates one // instance, hands it to the single library-items call whose result it will diff, and reads Count only // after that enumeration has completed. The API clients are long-lived singletons and scans for // different libraries run concurrently, so the counter must never be a field on a client or any // ambient/static state — that would leak one library's failures into another library's sweep decision. // Increments are interlocked anyway so a paginator that ever fans out stays correct. public sealed class MediaServerProjectionFailureCounter { private int _count; /// /// Number of items the server returned whose projection threw and was swallowed. /// public int Count => Volatile.Read(ref _count); public void RecordFailure() => Interlocked.Increment(ref _count); }