using ZB.MOM.WW.ScadaBridge.Commons.Entities.Kpi; namespace ZB.MOM.WW.ScadaBridge.KpiHistory; /// /// Root-provider-owned admission for source collections. Actor replacement must not /// start another call while an earlier cancellation-ignoring collection still owns its scope. /// Registration indices are stable because the root provider's service collection is immutable. /// internal sealed class KpiSourceAdmission { private readonly object _gate = new(); private readonly Dictionary>> _tasks = new(); /// /// Starts a collection for the given registration unless an earlier one is still running, in which case the running one is returned. /// /// Stable index of the source registration. /// Delegate that performs the collection when a new one is started. /// The new collection task, or the still-running earlier one. /// if a new collection was started; if an earlier one is still running. internal bool TryStart( int registrationIndex, Func>> collect, out Task> collection) { lock (_gate) { if (_tasks.TryGetValue(registrationIndex, out var existing) && !existing.IsCompleted) { collection = existing; return false; } collection = Task.Run(collect); _tasks[registrationIndex] = collection; return true; } } }