internal static void ToThingProperties(TheThing pThing, bool bReset) { lock (thingHarvestLock) { if (pThing == null) { return; } if (KPIIndexes == null) { CreateKPIIndexes(); } if (KPIs == null) { KPIs = new long[KPIIndexes.Count]; } if (KPIs != null && KPIIndexes != null) { TimeSpan timeSinceLastReset = DateTimeOffset.Now.Subtract(LastReset); bool resetReady = timeSinceLastReset.TotalMilliseconds >= 1000; foreach (var keyVal in KPIIndexes.GetDynamicEnumerable()) { bool donres = doNotReset.Contains(keyVal.Key); long kpiValue; if (bReset && !donres && resetReady) { kpiValue = Interlocked.Exchange(ref KPIs[keyVal.Value], 0); } else { kpiValue = Interlocked.Read(ref KPIs[keyVal.Value]); } // LastReset not set yet - shouldn't happen since it is set in first call to Reset (TheBaseAssets.InitAssets) if (LastReset == DateTimeOffset.MinValue || timeSinceLastReset.TotalSeconds <= 1 || donres) { pThing.SetProperty(keyVal.Key, kpiValue); } else { pThing.SetProperty(keyVal.Key, kpiValue / timeSinceLastReset.TotalSeconds); // Normalize value to "per second" } if (!doNotComputeTotals.Contains(keyVal.Key)) { pThing.SetProperty(keyVal.Key + "Total", TheThing.GetSafePropertyNumber(pThing, keyVal.Key + "Total") + kpiValue); } } if (bReset && resetReady) { LastReset = DateTimeOffset.Now; } // Grab some KPIs from sources - Workaround, this should be computed in the source instead SetKPI(eKPINames.QSenders, TheQueuedSenderRegistry.GetSenderListNodes().Count); SetKPI(eKPINames.QSenderInRegistry, TheQueuedSenderRegistry.Count()); SetKPI(eKPINames.SessionCount, TheBaseAssets.MySession.GetSessionCount()); SetKPI(eKPINames.UniqueMeshes, TheQueuedSenderRegistry.GetUniqueMeshCount()); SetKPI(eKPINames.UnsignedNodes, TheQueuedSenderRegistry.GetUnsignedNodeCount()); SetKPI(eKPINames.KnownNMINodes, Engines.NMIService.TheFormsGenerator.GetNMINodeCount()); SetKPI(eKPINames.StreamsNotFound, Communication.HttpService.TheHttpService.IsStreaming.Count); SetKPI(eKPINames.BlobsNotFound, Engines.ContentService.TheContentServiceEngine.BlobsNotHere.Count); } } }