public DynamicJsonValue GenerateDatabaseInfo() { Size size = new Size(GetAllStoragesEnvironment().Sum(env => env.Environment.Stats().AllocatedDataFileSizeInBytes)); var databaseInfo = new DynamicJsonValue { [nameof(ResourceInfo.Bundles)] = new DynamicJsonArray(BundleLoader.GetActiveBundles()), [nameof(ResourceInfo.IsAdmin)] = true, //TODO: implement me! [nameof(ResourceInfo.Name)] = Name, [nameof(ResourceInfo.Disabled)] = false, //TODO: this value should be overwritten by the studio since it is cached [nameof(ResourceInfo.TotalSize)] = new DynamicJsonValue { [nameof(Size.HumaneSize)] = size.HumaneSize, [nameof(Size.SizeInBytes)] = size.SizeInBytes }, [nameof(ResourceInfo.Errors)] = IndexStore.GetIndexes().Sum(index => index.GetErrors().Count), [nameof(ResourceInfo.Alerts)] = Alerts.GetAlertCount(), [nameof(ResourceInfo.UpTime)] = null, //it is shutting down [nameof(ResourceInfo.BackupInfo)] = BundleLoader.GetBackupInfo(), [nameof(DatabaseInfo.DocumentsCount)] = DocumentsStorage.GetNumberOfDocuments(), [nameof(DatabaseInfo.IndexesCount)] = IndexStore.GetIndexes().Count(), [nameof(DatabaseInfo.RejectClients)] = false, //TODO: implement me! [nameof(DatabaseInfo.IndexingStatus)] = IndexStore.Status.ToString(), [CachedDatabaseInfo] = true }; return(databaseInfo); }
private void InitializeInternal() { TxMerger.Start(); _indexStoreTask = IndexStore.InitializeAsync(); _transformerStoreTask = TransformerStore.InitializeAsync(); SqlReplicationLoader.Initialize(); DocumentTombstoneCleaner.Initialize(); BundleLoader = new BundleLoader(this); try { _indexStoreTask.Wait(DatabaseShutdown); } finally { _indexStoreTask = null; } try { _transformerStoreTask.Wait(DatabaseShutdown); } finally { _transformerStoreTask = null; } SubscriptionStorage.Initialize(); //Index Metadata Store shares Voron env and context pool with documents storage, //so replication of both documents and indexes/transformers can be made within one transaction ConfigurationStorage.Initialize(IndexStore, TransformerStore); DocumentReplicationLoader.Initialize(); }
public void Dispose() { //before we dispose of the database we take its latest info to be displayed in the studio var databaseInfo = GenerateDatabaseInfo(); DatabaseInfoCache?.InsertDatabaseInfo(databaseInfo, Name); _databaseShutdown.Cancel(); // we'll wait for 1 minute to drain all the requests // from the database for (int i = 0; i < 60; i++) { if (Interlocked.Read(ref _usages) == 0) { break; } _waitForUsagesOnDisposal.Wait(100); } var exceptionAggregator = new ExceptionAggregator(_logger, $"Could not dispose {nameof(DocumentDatabase)}"); foreach (var connection in RunningTcpConnections) { exceptionAggregator.Execute(() => { connection.Dispose(); }); } exceptionAggregator.Execute(() => { TxMerger.Dispose(); }); exceptionAggregator.Execute(() => { DocumentReplicationLoader.Dispose(); }); if (_indexStoreTask != null) { exceptionAggregator.Execute(() => { _indexStoreTask.Wait(DatabaseShutdown); _indexStoreTask = null; }); } if (_transformerStoreTask != null) { exceptionAggregator.Execute(() => { _transformerStoreTask.Wait(DatabaseShutdown); _transformerStoreTask = null; }); } exceptionAggregator.Execute(() => { IndexStore?.Dispose(); IndexStore = null; }); exceptionAggregator.Execute(() => { BundleLoader?.Dispose(); BundleLoader = null; }); exceptionAggregator.Execute(() => { DocumentTombstoneCleaner?.Dispose(); DocumentTombstoneCleaner = null; }); exceptionAggregator.Execute(() => { DocumentReplicationLoader?.Dispose(); DocumentReplicationLoader = null; }); exceptionAggregator.Execute(() => { SqlReplicationLoader?.Dispose(); SqlReplicationLoader = null; }); exceptionAggregator.Execute(() => { Operations?.Dispose(exceptionAggregator); Operations = null; }); exceptionAggregator.Execute(() => { SubscriptionStorage?.Dispose(); }); exceptionAggregator.Execute(() => { ConfigurationStorage?.Dispose(); }); exceptionAggregator.Execute(() => { DocumentsStorage?.Dispose(); DocumentsStorage = null; }); exceptionAggregator.ThrowIfNeeded(); }