PageRenderTime 44ms CodeModel.GetById 26ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 1ms

/Raven.Database/Server/RavenFS/RavenFileSystem.cs

https://github.com/nwendel/ravendb
C# | 239 lines | 208 code | 31 blank | 0 comment | 4 complexity | edc130133dc1a38680279755c36a8371 MD5 | raw file
  1using System;
  2using System.Collections.Generic;
  3using Raven.Abstractions.Data;
  4using System.Collections.Specialized;
  5using System.Diagnostics;
  6using System.IO;
  7using System.Linq;
  8using Raven.Abstractions.Util.Streams;
  9using Raven.Database.Config;
 10using Raven.Database.Server.Connections;
 11using Raven.Database.Server.RavenFS.Extensions;
 12using Raven.Database.Server.RavenFS.Infrastructure;
 13using Raven.Database.Server.RavenFS.Notifications;
 14using Raven.Database.Util;
 15using Raven.Database.Server.RavenFS.Search;
 16using Raven.Database.Server.RavenFS.Storage;
 17using Raven.Database.Server.RavenFS.Synchronization;
 18using Raven.Database.Server.RavenFS.Synchronization.Conflictuality;
 19using Raven.Database.Server.RavenFS.Synchronization.Rdc.Wrapper;
 20using Raven.Json.Linq;
 21using Raven.Abstractions.FileSystem;
 22
 23namespace Raven.Database.Server.RavenFS
 24{
 25	public class RavenFileSystem : IDisposable
 26	{
 27		private readonly ConflictArtifactManager conflictArtifactManager;
 28		private readonly ConflictDetector conflictDetector;
 29		private readonly ConflictResolver conflictResolver;
 30		private readonly FileLockManager fileLockManager;
 31		private readonly Historian historian;
 32		private readonly NotificationPublisher notificationPublisher;
 33		private readonly IndexStorage search;
 34		private readonly SigGenerator sigGenerator;
 35		private readonly ITransactionalStorage storage;
 36		private readonly StorageOperationsTask storageOperationsTask;
 37		private readonly SynchronizationTask synchronizationTask;
 38		private readonly InMemoryRavenConfiguration systemConfiguration;
 39	    private readonly TransportState transportState;
 40	    private readonly MetricsCountersManager metricsCounters;
 41
 42        public string Name { get; private set; }
 43
 44		public RavenFileSystem(InMemoryRavenConfiguration systemConfiguration, string name, TransportState recievedTransportState = null)
 45		{
 46		    this.Name = name;
 47			this.systemConfiguration = systemConfiguration;
 48
 49		    var storageType = systemConfiguration.DefaultFileSystemStorageTypeName;
 50            if (string.Equals(InMemoryRavenConfiguration.VoronTypeName, storageType, StringComparison.OrdinalIgnoreCase) == false)
 51            {
 52                if (Directory.Exists(systemConfiguration.FileSystemDataDirectory) &&
 53                        Directory.EnumerateFileSystemEntries(systemConfiguration.FileSystemDataDirectory).Any())
 54                    throw new InvalidOperationException(
 55                        string.Format(
 56                            "We do not allow to run on a storage engine other then Voron, while we are in the early pre-release phase of RavenDB 3.0. You are currently running on {0}",
 57                            storageType));
 58
 59                Trace.WriteLine("Forcing filesystem to run on Voron - pre release behavior only, mind " + Path.GetFileName(Path.GetDirectoryName(systemConfiguration.FileSystemDataDirectory)));
 60                storageType = InMemoryRavenConfiguration.VoronTypeName;
 61            }
 62
 63            storage = CreateTransactionalStorage(storageType, systemConfiguration);
 64			search = new IndexStorage(systemConfiguration.FileSystemIndexStoragePath, systemConfiguration.Settings);
 65			sigGenerator = new SigGenerator();
 66			var replicationHiLo = new SynchronizationHiLo(storage);
 67			var sequenceActions = new SequenceActions(storage);
 68			transportState = recievedTransportState ?? new TransportState();
 69			notificationPublisher = new NotificationPublisher(transportState);
 70			fileLockManager = new FileLockManager();
 71			storage.Initialize();
 72			search.Initialize();
 73			var uuidGenerator = new UuidGenerator(sequenceActions);
 74			historian = new Historian(storage, replicationHiLo, uuidGenerator);
 75			BufferPool = new BufferPool(1024 * 1024 * 1024, 65 * 1024);
 76			conflictArtifactManager = new ConflictArtifactManager(storage, search);
 77			conflictDetector = new ConflictDetector();
 78			conflictResolver = new ConflictResolver();
 79			synchronizationTask = new SynchronizationTask(storage, sigGenerator, notificationPublisher, systemConfiguration);
 80			storageOperationsTask = new StorageOperationsTask(storage, search, notificationPublisher);
 81            metricsCounters = new MetricsCountersManager();
 82
 83			AppDomain.CurrentDomain.ProcessExit += ShouldDispose;
 84			AppDomain.CurrentDomain.DomainUnload += ShouldDispose;
 85		}
 86
 87        private static ITransactionalStorage CreateTransactionalStorage(string storageType, InMemoryRavenConfiguration configuration)
 88        {
 89            switch (storageType)
 90            {
 91                case InMemoryRavenConfiguration.VoronTypeName:
 92					return new Storage.Voron.TransactionalStorage(configuration);
 93                default:
 94					return new Storage.Esent.TransactionalStorage(configuration);
 95            }
 96        }
 97
 98	    public ITransactionalStorage Storage
 99		{
100			get { return storage; }
101		}
102
103		public IndexStorage Search
104		{
105			get { return search; }
106		}
107
108		public BufferPool BufferPool { get; private set; }
109
110		public InMemoryRavenConfiguration Configuration
111		{
112			get { return systemConfiguration; }
113		}
114
115		public SigGenerator SigGenerator
116		{
117			get { return sigGenerator; }
118		}
119
120		public NotificationPublisher Publisher
121		{
122			get { return notificationPublisher; }
123		}
124
125		public Historian Historian
126		{
127			get { return historian; }
128		}
129
130		public FileLockManager FileLockManager
131		{
132			get { return fileLockManager; }
133		}
134
135		public SynchronizationTask SynchronizationTask
136		{
137			get { return synchronizationTask; }
138		}
139
140		public StorageOperationsTask StorageOperationsTask
141		{
142			get { return storageOperationsTask; }
143		}
144
145		public ConflictArtifactManager ConflictArtifactManager
146		{
147			get { return conflictArtifactManager; }
148		}
149
150		public ConflictDetector ConflictDetector
151		{
152			get { return conflictDetector; }
153		}
154
155		public ConflictResolver ConflictResolver
156		{
157			get { return conflictResolver; }
158		}
159
160	    public MetricsCountersManager MetricsCounters
161	    {
162	        get { return metricsCounters; }
163	    }
164
165		public TransportState TransportState
166		{
167			get { return transportState; }
168		}
169
170		public void Dispose()
171		{
172			AppDomain.CurrentDomain.ProcessExit -= ShouldDispose;
173			AppDomain.CurrentDomain.DomainUnload -= ShouldDispose;
174
175			storage.Dispose();
176			search.Dispose();
177			sigGenerator.Dispose();
178			BufferPool.Dispose();
179            metricsCounters.Dispose();
180		}
181
182        public FileSystemMetrics CreateMetrics()
183        {
184            var metrics = metricsCounters;
185
186            var percentiles = metrics.RequestDuationMetric.Percentiles(0.5, 0.75, 0.95, 0.99, 0.999, 0.9999);
187
188            return new FileSystemMetrics
189            {
190                RequestsPerSecond = Math.Round(metrics.RequestsPerSecondCounter.CurrentValue, 3),
191                FilesWritesPerSecond = Math.Round(metrics.FilesPerSecond.CurrentValue, 3),
192
193                RequestsDuration = new HistogramData
194                {
195                    Counter = metrics.RequestDuationMetric.Count,
196                    Max = metrics.RequestDuationMetric.Max,
197                    Mean = metrics.RequestDuationMetric.Mean,
198                    Min = metrics.RequestDuationMetric.Min,
199                    Stdev = metrics.RequestDuationMetric.StdDev,
200                    Percentiles = new Dictionary<string, double>
201                            {
202                                {"50%", percentiles[0]},
203                                {"75%", percentiles[1]},
204                                {"95%", percentiles[2]},
205                                {"99%", percentiles[3]},
206                                {"99.9%", percentiles[4]},
207                                {"99.99%", percentiles[5]},
208                            }
209                },
210                Requests = new MeterData
211                {
212                    Count = metrics.ConcurrentRequests.Count,
213                    FifteenMinuteRate = Math.Round(metrics.ConcurrentRequests.FifteenMinuteRate, 3),
214                    FiveMinuteRate = Math.Round(metrics.ConcurrentRequests.FiveMinuteRate, 3),
215                    MeanRate = Math.Round(metrics.ConcurrentRequests.MeanRate, 3),
216                    OneMinuteRate = Math.Round(metrics.ConcurrentRequests.OneMinuteRate, 3),
217                }
218            };
219        }
220
221		private void ShouldDispose(object sender, EventArgs eventArgs)
222		{
223			Dispose();
224		}
225
226	    public FileSystemStats GetFileSystemStats()
227	    {
228	        var fsStats = new FileSystemStats
229	        {
230	            Name = Name,
231	            Metrics = CreateMetrics(),
232	            ActiveSyncs = SynchronizationTask.Queue.Active.ToList(),
233	            PendingSyncs = SynchronizationTask.Queue.Pending.ToList(),
234	        };
235	        Storage.Batch(accessor => { fsStats.FileCount = accessor.GetFileCount(); });
236            return fsStats;
237	    }
238	}
239}