public static IEnumerable <AbstractDashboardNotification> FetchDatabasesInfo(ServerStore serverStore, Func <string, bool> isValidFor, CancellationTokenSource cts) { var databasesInfo = new DatabasesInfo(); var indexingSpeed = new IndexingSpeed(); var trafficWatch = new TrafficWatch(); var drivesUsage = new DrivesUsage(); trafficWatch.AverageRequestDuration = serverStore.Server.Metrics.Requests.AverageDuration.GetRate(); using (serverStore.ContextPool.AllocateOperationContext(out TransactionOperationContext transactionContext)) using (transactionContext.OpenReadTransaction()) { // 1. Fetch databases info foreach (var databaseTuple in serverStore.Cluster.ItemsStartingWith(transactionContext, Constants.Documents.Prefix, 0, int.MaxValue)) { var databaseName = databaseTuple.ItemName.Substring(Constants.Documents.Prefix.Length); if (cts.IsCancellationRequested) { yield break; } if (isValidFor != null && isValidFor(databaseName) == false) { continue; } if (serverStore.DatabasesLandlord.DatabasesCache.TryGetValue(databaseName, out var databaseTask) == false) { // database does not exist on this server, is offline or disabled SetOfflineDatabaseInfo(serverStore, transactionContext, databaseName, databasesInfo, drivesUsage, disabled: DatabasesLandlord.IsDatabaseDisabled(databaseTuple.Value)); continue; } try { var databaseOnline = IsDatabaseOnline(databaseTask, out var database); if (databaseOnline == false) { SetOfflineDatabaseInfo(serverStore, transactionContext, databaseName, databasesInfo, drivesUsage, disabled: false); continue; } var indexingSpeedItem = new IndexingSpeedItem { Database = database.Name, IndexedPerSecond = database.Metrics.MapIndexes.IndexedPerSec.OneSecondRate, MappedPerSecond = database.Metrics.MapReduceIndexes.MappedPerSec.OneSecondRate, ReducedPerSecond = database.Metrics.MapReduceIndexes.ReducedPerSec.OneSecondRate }; indexingSpeed.Items.Add(indexingSpeedItem); var replicationFactor = GetReplicationFactor(databaseTuple.Value); var documentsStorage = database.DocumentsStorage; var indexStorage = database.IndexStore; var trafficWatchItem = new TrafficWatchItem { Database = database.Name, RequestsPerSecond = (int)database.Metrics.Requests.RequestsPerSec.OneSecondRate, AverageRequestDuration = database.Metrics.Requests.AverageDuration.GetRate(), DocumentWritesPerSecond = (int)database.Metrics.Docs.PutsPerSec.OneSecondRate, AttachmentWritesPerSecond = (int)database.Metrics.Attachments.PutsPerSec.OneSecondRate, CounterWritesPerSecond = (int)database.Metrics.Counters.PutsPerSec.OneSecondRate, DocumentsWriteBytesPerSecond = database.Metrics.Docs.BytesPutsPerSec.OneSecondRate, AttachmentsWriteBytesPerSecond = database.Metrics.Attachments.BytesPutsPerSec.OneSecondRate, CountersWriteBytesPerSecond = database.Metrics.Counters.BytesPutsPerSec.OneSecondRate }; trafficWatch.Items.Add(trafficWatchItem); var currentEnvironmentsHash = database.GetEnvironmentsHash(); if (CachedDatabaseInfo.TryGetValue(database.Name, out var item) && item.Hash == currentEnvironmentsHash) { databasesInfo.Items.Add(item.Item); if (item.NextDiskSpaceCheck < SystemTime.UtcNow) { item.MountPoints = new List <Client.ServerWide.Operations.MountPointUsage>(); DiskUsageCheck(item, database, drivesUsage, cts); } else { foreach (var cachedMountPoint in item.MountPoints) { UpdateMountPoint(database.Configuration.Storage, cachedMountPoint, database.Name, drivesUsage); } } } else { using (documentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext documentsContext)) using (documentsContext.OpenReadTransaction()) { var databaseInfoItem = new DatabaseInfoItem { Database = database.Name, DocumentsCount = documentsStorage.GetNumberOfDocuments(documentsContext), IndexesCount = database.IndexStore.Count, AlertsCount = database.NotificationCenter.GetAlertCount(), ReplicationFactor = replicationFactor, ErroredIndexesCount = indexStorage.GetIndexes().Count(index => index.GetErrorCount() > 0), Online = true }; databasesInfo.Items.Add(databaseInfoItem); CachedDatabaseInfo[database.Name] = item = new DatabaseInfoCache { Hash = currentEnvironmentsHash, Item = databaseInfoItem }; } DiskUsageCheck(item, database, drivesUsage, cts); } } catch (Exception) { SetOfflineDatabaseInfo(serverStore, transactionContext, databaseName, databasesInfo, drivesUsage, disabled: false); } } // 2. Fetch <system> info if (isValidFor == null) { var currentSystemHash = serverStore._env.CurrentReadTransactionId; var cachedSystemInfoCopy = CachedSystemInfo; if (currentSystemHash != cachedSystemInfoCopy.Hash || cachedSystemInfoCopy.NextDiskSpaceCheck < SystemTime.UtcNow) { var systemInfo = new SystemInfoCache() { Hash = currentSystemHash, NextDiskSpaceCheck = SystemTime.UtcNow.AddSeconds(30), MountPoints = new List <Client.ServerWide.Operations.MountPointUsage>() }; // Get new data var systemEnv = new StorageEnvironmentWithType("<System>", StorageEnvironmentWithType.StorageEnvironmentType.System, serverStore._env); var systemMountPoints = ServerStore.GetMountPointUsageDetailsFor(systemEnv, includeTempBuffers: true); foreach (var systemPoint in systemMountPoints) { UpdateMountPoint(serverStore.Configuration.Storage, systemPoint, "<System>", drivesUsage); systemInfo.MountPoints.Add(systemPoint); } // Update the cache Interlocked.Exchange(ref CachedSystemInfo, systemInfo); } else { // Use existing data foreach (var systemPoint in cachedSystemInfoCopy.MountPoints) { UpdateMountPoint(serverStore.Configuration.Storage, systemPoint, "<System>", drivesUsage); } } } } yield return(databasesInfo); yield return(indexingSpeed); yield return(trafficWatch); yield return(drivesUsage); }