public void try_read_does_not_cache_anything_and_returns_record_once_it_is_written_later() { var writerchk = new InMemoryCheckpoint(0); var db = new TFChunkDb(new TFChunkDbConfig(PathName, new VersionedPatternFileNamingStrategy(PathName, "chunk-"), 10000, 0, writerchk, new InMemoryCheckpoint())); db.OpenVerifyAndClean(); var writer = new TFChunkWriter(db); writer.Open(); var reader = new TFChunkSequentialReader(db, writerchk, 0); LogRecord record; Assert.IsFalse(reader.TryReadNext(out record)); var rec = LogRecord.SingleWrite(0, Guid.NewGuid(), Guid.NewGuid(), "ES", -1, "ET", new byte[] { 7 }, null); long tmp; Assert.IsTrue(writer.Write(rec, out tmp)); writer.Flush(); writer.Close(); Assert.IsTrue(reader.TryReadNext(out record)); Assert.AreEqual(rec, record); reader.Close(); db.Close(); }
public override void TestFixtureSetUp() { base.TestFixtureSetUp(); WriterCheckpoint = new InMemoryCheckpoint(0); ChaserCheckpoint = new InMemoryCheckpoint(0); Bus = new InMemoryBus("bus"); IODispatcher = new IODispatcher(Bus, new PublishEnvelope(Bus)); Db = new TFChunkDb(new TFChunkDbConfig(PathName, new VersionedPatternFileNamingStrategy(PathName, "chunk-"), 10000, 0, WriterCheckpoint, ChaserCheckpoint, new InMemoryCheckpoint(-1), new InMemoryCheckpoint(-1))); Db.Open(); // create db Writer = new TFChunkWriter(Db); Writer.Open(); WriteTestScenario(); Writer.Close(); Writer = null; WriterCheckpoint.Flush(); ChaserCheckpoint.Write(WriterCheckpoint.Read()); ChaserCheckpoint.Flush(); var readers = new ObjectPool<ITransactionFileReader>("Readers", 2, 5, () => new TFChunkReader(Db, Db.Config.WriterCheckpoint)); var lowHasher = new XXHashUnsafe(); var highHasher = new Murmur3AUnsafe(); TableIndex = new TableIndex(GetFilePathFor("index"), lowHasher, highHasher, () => new HashListMemTable(PTableVersions.Index64Bit, MaxEntriesInMemTable * 2), () => new TFReaderLease(readers), PTableVersions.Index64Bit, MaxEntriesInMemTable); ReadIndex = new ReadIndex(new NoopPublisher(), readers, TableIndex, 0, additionalCommitChecks: true, metastreamMaxCount: MetastreamMaxCount, hashCollisionReadLimit: Opts.HashCollisionReadLimitDefault); ReadIndex.Init(ChaserCheckpoint.Read()); // scavenge must run after readIndex is built if (_scavenge) { if (_completeLastChunkOnScavenge) Db.Manager.GetChunk(Db.Manager.ChunksCount - 1).Complete(); _scavenger = new TFChunkScavenger(Db, IODispatcher, TableIndex, ReadIndex, Guid.NewGuid(), "fakeNodeIp"); _scavenger.Scavenge(alwaysKeepScavenged: true, mergeChunks: _mergeChunks); } }
public override void TestFixtureSetUp() { base.TestFixtureSetUp(); WriterCheckpoint = new InMemoryCheckpoint(0); ChaserCheckpoint = new InMemoryCheckpoint(0); Db = new TFChunkDb(new TFChunkDbConfig(PathName, new VersionedPatternFileNamingStrategy(PathName, "chunk-"), 10000, 0, WriterCheckpoint, ChaserCheckpoint, new InMemoryCheckpoint(-1), new InMemoryCheckpoint(-1))); Db.Open(); // create db Writer = new TFChunkWriter(Db); Writer.Open(); WriteTestScenario(); Writer.Close(); Writer = null; WriterCheckpoint.Flush(); ChaserCheckpoint.Write(WriterCheckpoint.Read()); ChaserCheckpoint.Flush(); var readers = new ObjectPool<ITransactionFileReader>("Readers", 2, 2, () => new TFChunkReader(Db, Db.Config.WriterCheckpoint)); TableIndex = new TableIndex(GetFilePathFor("index"), () => new HashListMemTable(MaxEntriesInMemTable * 2), () => new TFReaderLease(readers), MaxEntriesInMemTable); var hasher = new ByLengthHasher(); ReadIndex = new ReadIndex(new NoopPublisher(), readers, TableIndex, hasher, 0, additionalCommitChecks: true, metastreamMaxCount: MetastreamMaxCount); ReadIndex.Init(ChaserCheckpoint.Read()); // scavenge must run after readIndex is built if (_scavenge) { if (_completeLastChunkOnScavenge) Db.Manager.GetChunk(Db.Manager.ChunksCount - 1).Complete(); _scavenger = new TFChunkScavenger(Db, TableIndex, hasher, ReadIndex); _scavenger.Scavenge(alwaysKeepScavenged: true, mergeChunks: _mergeChunks); } }
public void a_record_can_be_written() { var filename = Path.Combine(PathName, "prefix.tf0"); var chunkHeader = new ChunkHeader(TFChunk.CurrentChunkVersion, 10000, 0, 0, 0); var chunkBytes = chunkHeader.AsByteArray(); var buf = new byte[ChunkHeader.Size + ChunkFooter.Size + chunkHeader.ChunkSize]; Buffer.BlockCopy(chunkBytes, 0, buf, 0, chunkBytes.Length); File.WriteAllBytes(filename, buf); _checkpoint = new InMemoryCheckpoint(137); var db = new TFChunkDb(new TFChunkDbConfig(PathName, new PrefixFileNamingStrategy(PathName, "prefix.tf"), chunkHeader.ChunkSize, 0, _checkpoint, new ICheckpoint[0])); db.OpenVerifyAndClean(); var writer = new TFChunkWriter(db); var record = new PrepareLogRecord(logPosition: 0, correlationId: _correlationId, eventId: _eventId, transactionPosition: 0, transactionOffset: 0, eventStreamId: "WorldEnding", expectedVersion: 1234, timeStamp: new DateTime(2012, 12, 21), flags: PrepareFlags.None, eventType: "type", data: new byte[8000], metadata: new byte[] { 7, 17 }); Console.WriteLine(record.GetSizeWithLengthPrefixAndSuffix()); Console.WriteLine(record.GetSizeWithLengthPrefixAndSuffix() + 137); long pos; Assert.IsTrue(writer.Write(record, out pos)); writer.Close(); db.Dispose(); Assert.AreEqual(record.GetSizeWithLengthPrefixAndSuffix() + 137, _checkpoint.Read()); using (var filestream = File.Open(filename, FileMode.Open, FileAccess.Read)) { filestream.Seek(ChunkHeader.Size + 137 + sizeof(int), SeekOrigin.Begin); var reader = new BinaryReader(filestream); var read = LogRecord.ReadFrom(reader); Console.WriteLine(string.Join("\n", Directory.EnumerateFiles(PathName))); Assert.AreEqual(record, read); } }
public override void TestFixtureSetUp() { base.TestFixtureSetUp(); WriterChecksum = new InMemoryCheckpoint(0); ChaserChecksum = new InMemoryCheckpoint(0); Db = new TFChunkDb(new TFChunkDbConfig(PathName, new VersionedPatternFileNamingStrategy(PathName, "chunk-"), 10000, 0, WriterChecksum, ChaserChecksum, new[] { WriterChecksum, ChaserChecksum })); Db.OpenVerifyAndClean(); // create db Writer = new TFChunkWriter(Db); Writer.Open(); WriteTestScenario(); Writer.Close(); Writer = null; WriterChecksum.Flush(); ChaserChecksum.Write(WriterChecksum.Read()); ChaserChecksum.Flush(); TableIndex = new TableIndex(GetFilePathFor("index"), () => new HashListMemTable(MaxEntriesInMemTable * 2), MaxEntriesInMemTable); var reader = new TFChunkReader(Db, Db.Config.WriterCheckpoint); ReadIndex = new ReadIndex(new NoopPublisher(), 2, () => new TFChunkSequentialReader(Db, Db.Config.WriterCheckpoint, 0), () => reader, TableIndex, new ByLengthHasher(), new NoLRUCache<string, StreamCacheInfo>()); ReadIndex.Build(); // scavenge must run after readIndex is built if (_scavenge) { if (_completeLastChunkOnScavenge) Db.Manager.GetChunk(Db.Manager.ChunksCount - 1).Complete(); _scavenger = new TFChunkScavenger(Db, ReadIndex); _scavenger.Scavenge(alwaysKeepScavenged: true); } }
public void a_record_can_be_written() { var filename = GetFilePathFor("chunk-000000.000000"); var chunkHeader = new ChunkHeader(TFChunk.CurrentChunkVersion, 10000, 0, 0, false, Guid.NewGuid()); var chunkBytes = chunkHeader.AsByteArray(); var buf = new byte[ChunkHeader.Size + ChunkFooter.Size + chunkHeader.ChunkSize]; Buffer.BlockCopy(chunkBytes, 0, buf, 0, chunkBytes.Length); File.WriteAllBytes(filename, buf); _checkpoint = new InMemoryCheckpoint(137); var db = new TFChunkDb(new TFChunkDbConfig(PathName, new VersionedPatternFileNamingStrategy(PathName, "chunk-"), chunkHeader.ChunkSize, 0, _checkpoint, new InMemoryCheckpoint(), new InMemoryCheckpoint(-1), new InMemoryCheckpoint(-1))); db.Open(); var bytes = new byte[3994]; // this gives exactly 4097 size of record, with 3993 (rec size 4096) everything works fine! new Random().NextBytes(bytes); var writer = new TFChunkWriter(db); var record = new PrepareLogRecord(logPosition: 137, correlationId: _correlationId, eventId: _eventId, transactionPosition: 789, transactionOffset: 543, eventStreamId: "WorldEnding", expectedVersion: 1234, timeStamp: new DateTime(2012, 12, 21), flags: PrepareFlags.SingleWrite, eventType: "type", data: bytes, metadata: new byte[] { 0x07, 0x17 }); long pos; Assert.IsTrue(writer.Write(record, out pos)); writer.Close(); db.Dispose(); Assert.AreEqual(record.GetSizeWithLengthPrefixAndSuffix() + 137, _checkpoint.Read()); using (var filestream = File.Open(filename, FileMode.Open, FileAccess.Read)) { filestream.Seek(ChunkHeader.Size + 137 + sizeof(int), SeekOrigin.Begin); var reader = new BinaryReader(filestream); var read = LogRecord.ReadFrom(reader); Assert.AreEqual(record, read); } }
public void a_record_can_be_written() { var filename = Path.Combine(PathName, "prefix.tf0"); var chunkHeader = new ChunkHeader(TFChunk.CurrentChunkVersion, 10000, 0, 0, 0); var chunkBytes = chunkHeader.AsByteArray(); var bytes = new byte[ChunkHeader.Size + 10000 + ChunkFooter.Size]; Buffer.BlockCopy(chunkBytes, 0, bytes, 0, chunkBytes.Length); File.WriteAllBytes(filename, bytes); _checkpoint = new InMemoryCheckpoint(137); var db = new TFChunkDb(new TFChunkDbConfig(PathName, new PrefixFileNamingStrategy(PathName, "prefix.tf"), 10000, 0, _checkpoint, new InMemoryCheckpoint(), new ICheckpoint[0])); db.OpenVerifyAndClean(); var tf = new TFChunkWriter(db); var record = new PrepareLogRecord(logPosition: 0, correlationId: _correlationId, eventId: _eventId, expectedVersion: 1234, transactionPosition: 0, transactionOffset: 0, eventStreamId: "WorldEnding", timeStamp: new DateTime(2012, 12, 21), flags: PrepareFlags.None, eventType: "type", data: new byte[] { 1, 2, 3, 4, 5 }, metadata: new byte[] { 7, 17 }); long tmp; tf.Write(record, out tmp); //tf.Flush(); tf.Close(); db.Dispose(); Assert.AreEqual(record.GetSizeWithLengthPrefixAndSuffix() + 137, _checkpoint.Read()); //137 is fluff assigned to beginning of checkpoint //TODO actually read the event using (var filestream = File.Open(filename, FileMode.Open, FileAccess.Read)) { filestream.Seek(ChunkHeader.Size + 137 + sizeof(int), SeekOrigin.Begin); var reader = new BinaryReader(filestream); var read = LogRecord.ReadFrom(reader); Assert.AreEqual(record, read); } }
public void a_record_can_be_written() { _checkpoint = new InMemoryCheckpoint(0); var db = new TFChunkDb(new TFChunkDbConfig(PathName, new VersionedPatternFileNamingStrategy(PathName, "chunk-"), 1000, 0, _checkpoint, new InMemoryCheckpoint(), new InMemoryCheckpoint(-1), new InMemoryCheckpoint(-1))); db.Open(); var tf = new TFChunkWriter(db); tf.Open(); var record = new PrepareLogRecord(logPosition: 0, correlationId: _correlationId, eventId: _eventId, transactionPosition: 0, transactionOffset: 0, eventStreamId: "WorldEnding", expectedVersion: 1234, timeStamp: new DateTime(2012, 12, 21), flags: PrepareFlags.None, eventType: "type", data: new byte[] { 1, 2, 3, 4, 5 }, metadata: new byte[] { 7, 17 }); long tmp; tf.Write(record, out tmp); tf.Close(); db.Dispose(); Assert.AreEqual(record.GetSizeWithLengthPrefixAndSuffix(), _checkpoint.Read()); using (var filestream = File.Open(GetFilePathFor("chunk-000000.000000"), FileMode.Open, FileAccess.Read)) { filestream.Position = ChunkHeader.Size; var reader = new BinaryReader(filestream); reader.ReadInt32(); var read = LogRecord.ReadFrom(reader); Assert.AreEqual(record, read); } }
public SingleVNode(TFChunkDb db, SingleVNodeSettings vNodeSettings, SingleVNodeAppSettings appSettings) { Ensure.NotNull(db, "db"); Ensure.NotNull(vNodeSettings, "vNodeSettings"); db.OpenVerifyAndClean(); _tcpEndPoint = vNodeSettings.ExternalTcpEndPoint; _httpEndPoint = vNodeSettings.HttpEndPoint; _outputBus = new InMemoryBus("OutputBus"); _controller = new SingleVNodeController(Bus, _httpEndPoint); _mainQueue = new QueuedHandler(_controller, "MainQueue"); _controller.SetMainQueue(MainQueue); //MONITORING var monitoringInnerBus = new InMemoryBus("MonitoringInnerBus", watchSlowMsg: false); var monitoringRequestBus = new InMemoryBus("MonitoringRequestBus", watchSlowMsg: false); var monitoringQueue = new QueuedHandler(monitoringInnerBus, "MonitoringQueue", watchSlowMsg: true, slowMsgThresholdMs: 100); var monitoring = new MonitoringService(monitoringQueue, monitoringRequestBus, db.Config.WriterCheckpoint, appSettings.StatsPeriod); Bus.Subscribe(monitoringQueue.WidenFrom<SystemMessage.SystemInit, Message>()); Bus.Subscribe(monitoringQueue.WidenFrom<SystemMessage.BecomeShuttingDown, Message>()); monitoringInnerBus.Subscribe<SystemMessage.SystemInit>(monitoring); monitoringInnerBus.Subscribe<SystemMessage.BecomeShuttingDown>(monitoring); monitoringInnerBus.Subscribe<MonitoringMessage.GetFreshStats>(monitoring); //STORAGE SUBSYSTEM var indexPath = Path.Combine(db.Config.Path, "index"); var tableIndex = new TableIndex(indexPath, () => new HashListMemTable(), new InMemoryCheckpoint(), maxSizeForMemory: 1000000, maxTablesPerLevel: 2); var readIndex = new ReadIndex(_mainQueue, db, () => new TFChunkReader(db, db.Config.WriterCheckpoint), TFConsts.ReadIndexReaderCount, db.Config.WriterCheckpoint, tableIndex, new XXHashUnsafe()); var writer = new TFChunkWriter(db); var storageWriter = new StorageWriter(_mainQueue, _outputBus, writer, readIndex); var storageReader = new StorageReader(_mainQueue, _outputBus, readIndex, TFConsts.StorageReaderHandlerCount); monitoringRequestBus.Subscribe<MonitoringMessage.InternalStatsRequest>(storageReader); var chaser = new TFChunkChaser(db, db.Config.WriterCheckpoint, db.Config.GetNamedCheckpoint(Checkpoint.Chaser)); var storageChaser = new StorageChaser(_mainQueue, chaser); _outputBus.Subscribe<SystemMessage.SystemInit>(storageChaser); _outputBus.Subscribe<SystemMessage.SystemStart>(storageChaser); _outputBus.Subscribe<SystemMessage.BecomeShuttingDown>(storageChaser); var storageScavenger = new StorageScavenger(db, readIndex); _outputBus.Subscribe<SystemMessage.ScavengeDatabase>(storageScavenger); //TCP var tcpService = new TcpService(MainQueue, _tcpEndPoint); Bus.Subscribe<SystemMessage.SystemInit>(tcpService); Bus.Subscribe<SystemMessage.SystemStart>(tcpService); Bus.Subscribe<SystemMessage.BecomeShuttingDown>(tcpService); //HTTP HttpService = new HttpService(MainQueue, _httpEndPoint.ToHttpUrl()); Bus.Subscribe<SystemMessage.SystemInit>(HttpService); Bus.Subscribe<SystemMessage.BecomeShuttingDown>(HttpService); Bus.Subscribe<HttpMessage.SendOverHttp>(HttpService); Bus.Subscribe<HttpMessage.UpdatePendingRequests>(HttpService); HttpService.SetupController(new AdminController(MainQueue)); HttpService.SetupController(new PingController()); HttpService.SetupController(new StatController(monitoringQueue)); HttpService.SetupController(new ReadEventDataController(MainQueue)); HttpService.SetupController(new AtomController(MainQueue)); HttpService.SetupController(new WebSiteController(MainQueue)); //REQUEST MANAGEMENT var requestManagement = new RequestManagementService(MainQueue, 1, 1); Bus.Subscribe<ReplicationMessage.EventCommited>(requestManagement); Bus.Subscribe<ReplicationMessage.CreateStreamRequestCreated>(requestManagement); Bus.Subscribe<ReplicationMessage.WriteRequestCreated>(requestManagement); Bus.Subscribe<ReplicationMessage.TransactionStartRequestCreated>(requestManagement); Bus.Subscribe<ReplicationMessage.TransactionWriteRequestCreated>(requestManagement); Bus.Subscribe<ReplicationMessage.TransactionCommitRequestCreated>(requestManagement); Bus.Subscribe<ReplicationMessage.DeleteStreamRequestCreated>(requestManagement); Bus.Subscribe<ReplicationMessage.RequestCompleted>(requestManagement); Bus.Subscribe<ReplicationMessage.CommitAck>(requestManagement); Bus.Subscribe<ReplicationMessage.PrepareAck>(requestManagement); Bus.Subscribe<ReplicationMessage.WrongExpectedVersion>(requestManagement); Bus.Subscribe<ReplicationMessage.InvalidTransaction>(requestManagement); Bus.Subscribe<ReplicationMessage.StreamDeleted>(requestManagement); Bus.Subscribe<ReplicationMessage.PreparePhaseTimeout>(requestManagement); Bus.Subscribe<ReplicationMessage.CommitPhaseTimeout>(requestManagement); var clientService = new ClientService(); Bus.Subscribe<TcpMessage.ConnectionClosed>(clientService); Bus.Subscribe<ClientMessage.SubscribeToStream>(clientService); Bus.Subscribe<ClientMessage.UnsubscribeFromStream>(clientService); Bus.Subscribe<ClientMessage.SubscribeToAllStreams>(clientService); Bus.Subscribe<ClientMessage.UnsubscribeFromAllStreams>(clientService); Bus.Subscribe<ReplicationMessage.EventCommited>(clientService); //TIMER //var timer = new TimerService(new TimerBasedScheduler(new RealTimer(), new RealTimeProvider())); TimerService = new TimerService(new ThreadBasedScheduler(new RealTimeProvider())); Bus.Subscribe<TimerMessage.Schedule>(TimerService); MainQueue.Start(); monitoringQueue.Start(); }
public void a_record_is_not_written_at_first_but_written_on_second_try() { var filename1 = Path.Combine(PathName, "prefix.tf0"); var filename2 = Path.Combine(PathName, "prefix.tf1"); var chunkHeader = new ChunkHeader(TFChunk.CurrentChunkVersion, 10000, 0, 0, 0); var chunkBytes = chunkHeader.AsByteArray(); var bytes = new byte[ChunkHeader.Size + 10000 + ChunkFooter.Size]; Buffer.BlockCopy(chunkBytes, 0, bytes, 0, chunkBytes.Length); File.WriteAllBytes(filename1, bytes); _checkpoint = new InMemoryCheckpoint(0); var db = new TFChunkDb(new TFChunkDbConfig(PathName, new PrefixFileNamingStrategy(PathName, "prefix.tf"), 10000, 0, _checkpoint, new ICheckpoint[0])); db.OpenVerifyAndClean(); var tf = new TFChunkWriter(db); long pos; var record1 = new PrepareLogRecord(logPosition: 0, correlationId: _correlationId, eventId: _eventId, expectedVersion: 1234, transactionPosition: 0, transactionOffset: 0, eventStreamId: "WorldEnding", timeStamp: new DateTime(2012, 12, 21), flags: PrepareFlags.None, eventType: "type", data: new byte[] { 1, 2, 3, 4, 5 }, metadata: new byte[8000]); Assert.IsTrue(tf.Write(record1, out pos)); // almost fill up first chunk var record2 = new PrepareLogRecord(logPosition: pos, correlationId: _correlationId, eventId: _eventId, expectedVersion: 1234, transactionPosition: pos, transactionOffset: 0, eventStreamId: "WorldEnding", timeStamp: new DateTime(2012, 12, 21), flags: PrepareFlags.None, eventType: "type", data: new byte[] { 1, 2, 3, 4, 5 }, metadata: new byte[8000]); Assert.IsFalse(tf.Write(record2, out pos)); // chunk has too small space var record3 = new PrepareLogRecord(logPosition: pos, correlationId: _correlationId, eventId: _eventId, expectedVersion: 1234, transactionPosition: pos, transactionOffset: 0, eventStreamId: "WorldEnding", timeStamp: new DateTime(2012, 12, 21), flags: PrepareFlags.None, eventType: "type", data: new byte[] { 1, 2, 3, 4, 5 }, metadata: new byte[2000]); Assert.IsTrue(tf.Write(record3, out pos)); tf.Close(); db.Dispose(); Assert.AreEqual(record3.GetSizeWithLengthPrefixAndSuffix() + 10000, _checkpoint.Read()); using (var filestream = File.Open(filename2, FileMode.Open, FileAccess.Read)) { filestream.Seek(ChunkHeader.Size + sizeof(int), SeekOrigin.Begin); var reader = new BinaryReader(filestream); var read = LogRecord.ReadFrom(reader); Assert.AreEqual(record3, read); } }
public SingleVNode(TFChunkDb db, SingleVNodeSettings vNodeSettings, bool dbVerifyHashes, int memTableEntryCount, params ISubsystem[] subsystems) { Ensure.NotNull(db, "db"); Ensure.NotNull(vNodeSettings, "vNodeSettings"); _settings = vNodeSettings; _mainBus = new InMemoryBus("MainBus"); _controller = new SingleVNodeController(_mainBus, _settings.ExternalHttpEndPoint, db, this); _mainQueue = new QueuedHandler(_controller, "MainQueue"); _controller.SetMainQueue(_mainQueue); _subsystems = subsystems; // MONITORING var monitoringInnerBus = new InMemoryBus("MonitoringInnerBus", watchSlowMsg: false); var monitoringRequestBus = new InMemoryBus("MonitoringRequestBus", watchSlowMsg: false); var monitoringQueue = new QueuedHandlerThreadPool(monitoringInnerBus, "MonitoringQueue", true, TimeSpan.FromMilliseconds(100)); var monitoring = new MonitoringService(monitoringQueue, monitoringRequestBus, _mainQueue, db.Config.WriterCheckpoint, db.Config.Path, vNodeSettings.StatsPeriod, _settings.ExternalHttpEndPoint, vNodeSettings.StatsStorage); _mainBus.Subscribe(monitoringQueue.WidenFrom<SystemMessage.SystemInit, Message>()); _mainBus.Subscribe(monitoringQueue.WidenFrom<SystemMessage.StateChangeMessage, Message>()); _mainBus.Subscribe(monitoringQueue.WidenFrom<SystemMessage.BecomeShuttingDown, Message>()); _mainBus.Subscribe(monitoringQueue.WidenFrom<SystemMessage.BecomeShutdown, Message>()); _mainBus.Subscribe(monitoringQueue.WidenFrom<ClientMessage.WriteEventsCompleted, Message>()); monitoringInnerBus.Subscribe<SystemMessage.SystemInit>(monitoring); monitoringInnerBus.Subscribe<SystemMessage.StateChangeMessage>(monitoring); monitoringInnerBus.Subscribe<SystemMessage.BecomeShuttingDown>(monitoring); monitoringInnerBus.Subscribe<SystemMessage.BecomeShutdown>(monitoring); monitoringInnerBus.Subscribe<ClientMessage.WriteEventsCompleted>(monitoring); monitoringInnerBus.Subscribe<MonitoringMessage.GetFreshStats>(monitoring); var truncPos = db.Config.TruncateCheckpoint.Read(); if (truncPos != -1) { Log.Info("Truncate checkpoint is present. Truncate: {0} (0x{0:X}), Writer: {1} (0x{1:X}), Chaser: {2} (0x{2:X}), Epoch: {3} (0x{3:X})", truncPos, db.Config.WriterCheckpoint.Read(), db.Config.ChaserCheckpoint.Read(), db.Config.EpochCheckpoint.Read()); var truncator = new TFChunkDbTruncator(db.Config); truncator.TruncateDb(truncPos); } db.Open(dbVerifyHashes); // STORAGE SUBSYSTEM var indexPath = Path.Combine(db.Config.Path, "index"); var readerPool = new ObjectPool<ITransactionFileReader>( "ReadIndex readers pool", ESConsts.PTableInitialReaderCount, ESConsts.PTableMaxReaderCount, () => new TFChunkReader(db, db.Config.WriterCheckpoint)); var tableIndex = new TableIndex(indexPath, () => new HashListMemTable(maxSize: memTableEntryCount * 2), () => new TFReaderLease(readerPool), maxSizeForMemory: memTableEntryCount, maxTablesPerLevel: 2, inMem: db.Config.InMemDb); var hasher = new XXHashUnsafe(); var readIndex = new ReadIndex(_mainQueue, readerPool, tableIndex, hasher, ESConsts.StreamInfoCacheCapacity, Application.IsDefined(Application.AdditionalCommitChecks), Application.IsDefined(Application.InfiniteMetastreams) ? int.MaxValue : 1); var writer = new TFChunkWriter(db); var epochManager = new EpochManager(ESConsts.CachedEpochCount, db.Config.EpochCheckpoint, writer, initialReaderCount: 1, maxReaderCount: 5, readerFactory: () => new TFChunkReader(db, db.Config.WriterCheckpoint)); epochManager.Init(); var storageWriter = new StorageWriterService(_mainQueue, _mainBus, _settings.MinFlushDelay, db, writer, readIndex.IndexWriter, epochManager); // subscribes internally monitoringRequestBus.Subscribe<MonitoringMessage.InternalStatsRequest>(storageWriter); var storageReader = new StorageReaderService(_mainQueue, _mainBus, readIndex, ESConsts.StorageReaderThreadCount, db.Config.WriterCheckpoint); _mainBus.Subscribe<SystemMessage.SystemInit>(storageReader); _mainBus.Subscribe<SystemMessage.BecomeShuttingDown>(storageReader); _mainBus.Subscribe<SystemMessage.BecomeShutdown>(storageReader); monitoringRequestBus.Subscribe<MonitoringMessage.InternalStatsRequest>(storageReader); var chaser = new TFChunkChaser(db, db.Config.WriterCheckpoint, db.Config.ChaserCheckpoint); var storageChaser = new StorageChaser(_mainQueue, db.Config.WriterCheckpoint, chaser, readIndex.IndexCommitter, epochManager); _mainBus.Subscribe<SystemMessage.SystemInit>(storageChaser); _mainBus.Subscribe<SystemMessage.SystemStart>(storageChaser); _mainBus.Subscribe<SystemMessage.BecomeShuttingDown>(storageChaser); var storageScavenger = new StorageScavenger(db, tableIndex, hasher, readIndex, Application.IsDefined(Application.AlwaysKeepScavenged), mergeChunks: false /*!Application.IsDefined(Application.DisableMergeChunks)*/); // ReSharper disable RedundantTypeArgumentsOfMethod _mainBus.Subscribe<ClientMessage.ScavengeDatabase>(storageScavenger); // ReSharper restore RedundantTypeArgumentsOfMethod // MISC WORKERS _workerBuses = Enumerable.Range(0, vNodeSettings.WorkerThreads).Select(queueNum => new InMemoryBus(string.Format("Worker #{0} Bus", queueNum + 1), watchSlowMsg: true, slowMsgThreshold: TimeSpan.FromMilliseconds(200))).ToArray(); _workersHandler = new MultiQueuedHandler( vNodeSettings.WorkerThreads, queueNum => new QueuedHandlerThreadPool(_workerBuses[queueNum], string.Format("Worker #{0}", queueNum + 1), groupName: "Workers", watchSlowMsg: true, slowMsgThreshold: TimeSpan.FromMilliseconds(200))); // AUTHENTICATION INFRASTRUCTURE var passwordHashAlgorithm = new Rfc2898PasswordHashAlgorithm(); var dispatcher = new IODispatcher(_mainQueue, new PublishEnvelope(_workersHandler, crossThread: true)); var internalAuthenticationProvider = new InternalAuthenticationProvider(dispatcher, passwordHashAlgorithm, ESConsts.CachedPrincipalCount); var passwordChangeNotificationReader = new PasswordChangeNotificationReader(_mainQueue, dispatcher); _mainBus.Subscribe<SystemMessage.SystemStart>(passwordChangeNotificationReader); _mainBus.Subscribe<SystemMessage.BecomeShutdown>(passwordChangeNotificationReader); _mainBus.Subscribe(internalAuthenticationProvider); SubscribeWorkers(bus => { bus.Subscribe(dispatcher.ForwardReader); bus.Subscribe(dispatcher.BackwardReader); bus.Subscribe(dispatcher.Writer); bus.Subscribe(dispatcher.StreamDeleter); bus.Subscribe(dispatcher); }); // TCP { var tcpService = new TcpService(_mainQueue, _settings.ExternalTcpEndPoint, _workersHandler, TcpServiceType.External, TcpSecurityType.Normal, new ClientTcpDispatcher(), ESConsts.ExternalHeartbeatInterval, ESConsts.ExternalHeartbeatTimeout, internalAuthenticationProvider, null); _mainBus.Subscribe<SystemMessage.SystemInit>(tcpService); _mainBus.Subscribe<SystemMessage.SystemStart>(tcpService); _mainBus.Subscribe<SystemMessage.BecomeShuttingDown>(tcpService); } // SECURE TCP if (vNodeSettings.ExternalSecureTcpEndPoint != null) { var secureTcpService = new TcpService(_mainQueue, _settings.ExternalSecureTcpEndPoint, _workersHandler, TcpServiceType.External, TcpSecurityType.Secure, new ClientTcpDispatcher(), ESConsts.ExternalHeartbeatInterval, ESConsts.ExternalHeartbeatTimeout, internalAuthenticationProvider, _settings.Certificate); _mainBus.Subscribe<SystemMessage.SystemInit>(secureTcpService); _mainBus.Subscribe<SystemMessage.SystemStart>(secureTcpService); _mainBus.Subscribe<SystemMessage.BecomeShuttingDown>(secureTcpService); } SubscribeWorkers(bus => { var tcpSendService = new TcpSendService(); // ReSharper disable RedundantTypeArgumentsOfMethod bus.Subscribe<TcpMessage.TcpSend>(tcpSendService); // ReSharper restore RedundantTypeArgumentsOfMethod }); // HTTP var httpAuthenticationProviders = new List<HttpAuthenticationProvider> { new BasicHttpAuthenticationProvider(internalAuthenticationProvider), }; if (_settings.EnableTrustedAuth) httpAuthenticationProviders.Add(new TrustedHttpAuthenticationProvider()); httpAuthenticationProviders.Add(new AnonymousHttpAuthenticationProvider()); var httpPipe = new HttpMessagePipe(); var httpSendService = new HttpSendService(httpPipe, forwardRequests: false); _mainBus.Subscribe<SystemMessage.StateChangeMessage>(httpSendService); _mainBus.Subscribe(new WideningHandler<HttpMessage.SendOverHttp, Message>(_workersHandler)); SubscribeWorkers(bus => { bus.Subscribe<HttpMessage.HttpSend>(httpSendService); bus.Subscribe<HttpMessage.HttpSendPart>(httpSendService); bus.Subscribe<HttpMessage.HttpBeginSend>(httpSendService); bus.Subscribe<HttpMessage.HttpEndSend>(httpSendService); bus.Subscribe<HttpMessage.SendOverHttp>(httpSendService); }); _httpService = new HttpService(ServiceAccessibility.Public, _mainQueue, new TrieUriRouter(), _workersHandler, vNodeSettings.HttpPrefixes); _httpService.SetupController(new AdminController(_mainQueue)); _httpService.SetupController(new PingController()); _httpService.SetupController(new StatController(monitoringQueue, _workersHandler)); _httpService.SetupController(new AtomController(httpSendService, _mainQueue, _workersHandler)); _httpService.SetupController(new GuidController(_mainQueue)); _httpService.SetupController(new UsersController(httpSendService, _mainQueue, _workersHandler)); _mainBus.Subscribe<SystemMessage.SystemInit>(_httpService); _mainBus.Subscribe<SystemMessage.BecomeShuttingDown>(_httpService); _mainBus.Subscribe<HttpMessage.PurgeTimedOutRequests>(_httpService); SubscribeWorkers(bus => { HttpService.CreateAndSubscribePipeline(bus, httpAuthenticationProviders.ToArray()); }); // REQUEST MANAGEMENT var requestManagement = new RequestManagementService(_mainQueue, 1, 1, vNodeSettings.PrepareTimeout, vNodeSettings.CommitTimeout); _mainBus.Subscribe<SystemMessage.SystemInit>(requestManagement); _mainBus.Subscribe<ClientMessage.WriteEvents>(requestManagement); _mainBus.Subscribe<ClientMessage.TransactionStart>(requestManagement); _mainBus.Subscribe<ClientMessage.TransactionWrite>(requestManagement); _mainBus.Subscribe<ClientMessage.TransactionCommit>(requestManagement); _mainBus.Subscribe<ClientMessage.DeleteStream>(requestManagement); _mainBus.Subscribe<StorageMessage.RequestCompleted>(requestManagement); _mainBus.Subscribe<StorageMessage.CheckStreamAccessCompleted>(requestManagement); _mainBus.Subscribe<StorageMessage.AlreadyCommitted>(requestManagement); _mainBus.Subscribe<StorageMessage.CommitAck>(requestManagement); _mainBus.Subscribe<StorageMessage.PrepareAck>(requestManagement); _mainBus.Subscribe<StorageMessage.WrongExpectedVersion>(requestManagement); _mainBus.Subscribe<StorageMessage.InvalidTransaction>(requestManagement); _mainBus.Subscribe<StorageMessage.StreamDeleted>(requestManagement); _mainBus.Subscribe<StorageMessage.RequestManagerTimerTick>(requestManagement); // SUBSCRIPTIONS var subscrBus = new InMemoryBus("SubscriptionsBus", true, TimeSpan.FromMilliseconds(50)); var subscrQueue = new QueuedHandlerThreadPool(subscrBus, "Subscriptions", false); _mainBus.Subscribe(subscrQueue.WidenFrom<SystemMessage.SystemStart, Message>()); _mainBus.Subscribe(subscrQueue.WidenFrom<SystemMessage.BecomeShuttingDown, Message>()); _mainBus.Subscribe(subscrQueue.WidenFrom<TcpMessage.ConnectionClosed, Message>()); _mainBus.Subscribe(subscrQueue.WidenFrom<ClientMessage.SubscribeToStream, Message>()); _mainBus.Subscribe(subscrQueue.WidenFrom<ClientMessage.UnsubscribeFromStream, Message>()); _mainBus.Subscribe(subscrQueue.WidenFrom<SubscriptionMessage.PollStream, Message>()); _mainBus.Subscribe(subscrQueue.WidenFrom<SubscriptionMessage.CheckPollTimeout, Message>()); _mainBus.Subscribe(subscrQueue.WidenFrom<StorageMessage.EventCommited, Message>()); var subscription = new SubscriptionsService(_mainQueue, subscrQueue, readIndex); subscrBus.Subscribe<SystemMessage.SystemStart>(subscription); subscrBus.Subscribe<SystemMessage.BecomeShuttingDown>(subscription); subscrBus.Subscribe<TcpMessage.ConnectionClosed>(subscription); subscrBus.Subscribe<ClientMessage.SubscribeToStream>(subscription); subscrBus.Subscribe<ClientMessage.UnsubscribeFromStream>(subscription); subscrBus.Subscribe<SubscriptionMessage.PollStream>(subscription); subscrBus.Subscribe<SubscriptionMessage.CheckPollTimeout>(subscription); subscrBus.Subscribe<StorageMessage.EventCommited>(subscription); // USER MANAGEMENT var ioDispatcher = new IODispatcher(_mainQueue, new PublishEnvelope(_mainQueue)); _mainBus.Subscribe(ioDispatcher.BackwardReader); _mainBus.Subscribe(ioDispatcher.ForwardReader); _mainBus.Subscribe(ioDispatcher.Writer); _mainBus.Subscribe(ioDispatcher.StreamDeleter); _mainBus.Subscribe(ioDispatcher); var userManagement = new UserManagementService( _mainQueue, ioDispatcher, passwordHashAlgorithm, vNodeSettings.SkipInitializeStandardUsersCheck); _mainBus.Subscribe<UserManagementMessage.Create>(userManagement); _mainBus.Subscribe<UserManagementMessage.Update>(userManagement); _mainBus.Subscribe<UserManagementMessage.Enable>(userManagement); _mainBus.Subscribe<UserManagementMessage.Disable>(userManagement); _mainBus.Subscribe<UserManagementMessage.Delete>(userManagement); _mainBus.Subscribe<UserManagementMessage.ResetPassword>(userManagement); _mainBus.Subscribe<UserManagementMessage.ChangePassword>(userManagement); _mainBus.Subscribe<UserManagementMessage.Get>(userManagement); _mainBus.Subscribe<UserManagementMessage.GetAll>(userManagement); _mainBus.Subscribe<SystemMessage.BecomeMaster>(userManagement); // TIMER _timeProvider = new RealTimeProvider(); _timerService = new TimerService(new ThreadBasedScheduler(_timeProvider)); _mainBus.Subscribe<SystemMessage.BecomeShutdown>(_timerService); _mainBus.Subscribe<TimerMessage.Schedule>(_timerService); _workersHandler.Start(); _mainQueue.Start(); monitoringQueue.Start(); subscrQueue.Start(); if (subsystems != null) foreach (var subsystem in subsystems) subsystem.Register(db, _mainQueue, _mainBus, _timerService, _timeProvider, httpSendService, new[]{_httpService}, _workersHandler); }
public ClusterVNode(TFChunkDb db, ClusterVNodeSettings vNodeSettings, IGossipSeedSource gossipSeedSource, bool dbVerifyHashes, int memTableEntryCount, params ISubsystem[] subsystems) { Ensure.NotNull(db, "db"); Ensure.NotNull(vNodeSettings, "vNodeSettings"); Ensure.NotNull(gossipSeedSource, "gossipSeedSource"); _nodeInfo = vNodeSettings.NodeInfo; _mainBus = new InMemoryBus("MainBus"); var forwardingProxy = new MessageForwardingProxy(); // MISC WORKERS _workerBuses = Enumerable.Range(0, vNodeSettings.WorkerThreads).Select(queueNum => new InMemoryBus(string.Format("Worker #{0} Bus", queueNum + 1), watchSlowMsg: true, slowMsgThreshold: TimeSpan.FromMilliseconds(200))).ToArray(); _workersHandler = new MultiQueuedHandler( vNodeSettings.WorkerThreads, queueNum => new QueuedHandlerThreadPool(_workerBuses[queueNum], string.Format("Worker #{0}", queueNum + 1), groupName: "Workers", watchSlowMsg: true, slowMsgThreshold: TimeSpan.FromMilliseconds(200))); _controller = new ClusterVNodeController(_mainBus, _nodeInfo, db, vNodeSettings, this, forwardingProxy); _mainQueue = new QueuedHandler(_controller, "MainQueue"); _controller.SetMainQueue(_mainQueue); _subsystems = subsystems; // MONITORING var monitoringInnerBus = new InMemoryBus("MonitoringInnerBus", watchSlowMsg: false); var monitoringRequestBus = new InMemoryBus("MonitoringRequestBus", watchSlowMsg: false); var monitoringQueue = new QueuedHandlerThreadPool(monitoringInnerBus, "MonitoringQueue", true, TimeSpan.FromMilliseconds(100)); var monitoring = new MonitoringService(monitoringQueue, monitoringRequestBus, _mainQueue, db.Config.WriterCheckpoint, db.Config.Path, vNodeSettings.StatsPeriod, _nodeInfo.ExternalHttp, vNodeSettings.StatsStorage); _mainBus.Subscribe(monitoringQueue.WidenFrom<SystemMessage.SystemInit, Message>()); _mainBus.Subscribe(monitoringQueue.WidenFrom<SystemMessage.StateChangeMessage, Message>()); _mainBus.Subscribe(monitoringQueue.WidenFrom<SystemMessage.BecomeShuttingDown, Message>()); _mainBus.Subscribe(monitoringQueue.WidenFrom<SystemMessage.BecomeShutdown, Message>()); _mainBus.Subscribe(monitoringQueue.WidenFrom<ClientMessage.WriteEventsCompleted, Message>()); monitoringInnerBus.Subscribe<SystemMessage.SystemInit>(monitoring); monitoringInnerBus.Subscribe<SystemMessage.StateChangeMessage>(monitoring); monitoringInnerBus.Subscribe<SystemMessage.BecomeShuttingDown>(monitoring); monitoringInnerBus.Subscribe<SystemMessage.BecomeShutdown>(monitoring); monitoringInnerBus.Subscribe<ClientMessage.WriteEventsCompleted>(monitoring); monitoringInnerBus.Subscribe<MonitoringMessage.GetFreshStats>(monitoring); var truncPos = db.Config.TruncateCheckpoint.Read(); if (truncPos != -1) { Log.Info("Truncate checkpoint is present. Truncate: {0} (0x{0:X}), Writer: {1} (0x{1:X}), Chaser: {2} (0x{2:X}), Epoch: {3} (0x{3:X})", truncPos, db.Config.WriterCheckpoint.Read(), db.Config.ChaserCheckpoint.Read(), db.Config.EpochCheckpoint.Read()); var truncator = new TFChunkDbTruncator(db.Config); truncator.TruncateDb(truncPos); } // STORAGE SUBSYSTEM db.Open(dbVerifyHashes); var indexPath = Path.Combine(db.Config.Path, "index"); var readerPool = new ObjectPool<ITransactionFileReader>( "ReadIndex readers pool", ESConsts.PTableInitialReaderCount, ESConsts.PTableMaxReaderCount, () => new TFChunkReader(db, db.Config.WriterCheckpoint)); var tableIndex = new TableIndex(indexPath, () => new HashListMemTable(maxSize: memTableEntryCount * 2), () => new TFReaderLease(readerPool), maxSizeForMemory: memTableEntryCount, maxTablesPerLevel: 2, inMem: db.Config.InMemDb); var hash = new XXHashUnsafe(); var readIndex = new ReadIndex(_mainQueue, readerPool, tableIndex, hash, ESConsts.StreamInfoCacheCapacity, Application.IsDefined(Application.AdditionalCommitChecks), Application.IsDefined(Application.InfiniteMetastreams) ? int.MaxValue : 1); var writer = new TFChunkWriter(db); var epochManager = new EpochManager(ESConsts.CachedEpochCount, db.Config.EpochCheckpoint, writer, initialReaderCount: 1, maxReaderCount: 5, readerFactory: () => new TFChunkReader(db, db.Config.WriterCheckpoint)); epochManager.Init(); var storageWriter = new ClusterStorageWriterService(_mainQueue, _mainBus, vNodeSettings.MinFlushDelay, db, writer, readIndex.IndexWriter, epochManager, () => readIndex.LastCommitPosition); // subscribes internally monitoringRequestBus.Subscribe<MonitoringMessage.InternalStatsRequest>(storageWriter); var storageReader = new StorageReaderService(_mainQueue, _mainBus, readIndex, ESConsts.StorageReaderThreadCount, db.Config.WriterCheckpoint); _mainBus.Subscribe<SystemMessage.SystemInit>(storageReader); _mainBus.Subscribe<SystemMessage.BecomeShuttingDown>(storageReader); _mainBus.Subscribe<SystemMessage.BecomeShutdown>(storageReader); monitoringRequestBus.Subscribe<MonitoringMessage.InternalStatsRequest>(storageReader); var chaser = new TFChunkChaser(db, db.Config.WriterCheckpoint, db.Config.ChaserCheckpoint); var storageChaser = new StorageChaser(_mainQueue, db.Config.WriterCheckpoint, chaser, readIndex.IndexCommitter, epochManager); _mainBus.Subscribe<SystemMessage.SystemInit>(storageChaser); _mainBus.Subscribe<SystemMessage.SystemStart>(storageChaser); _mainBus.Subscribe<SystemMessage.BecomeShuttingDown>(storageChaser); var storageScavenger = new StorageScavenger(db, tableIndex, hash, readIndex, Application.IsDefined(Application.AlwaysKeepScavenged), mergeChunks: !vNodeSettings.DisableScavengeMerging); // ReSharper disable RedundantTypeArgumentsOfMethod _mainBus.Subscribe<ClientMessage.ScavengeDatabase>(storageScavenger); // ReSharper restore RedundantTypeArgumentsOfMethod // AUTHENTICATION INFRASTRUCTURE - delegate to plugins var authenticationProvider = vNodeSettings.AuthenticationProviderFactory.BuildAuthenticationProvider(_mainQueue, _mainBus, _workersHandler, _workerBuses); Ensure.NotNull(authenticationProvider, "authenticationProvider"); { // EXTERNAL TCP var extTcpService = new TcpService(_mainQueue, _nodeInfo.ExternalTcp, _workersHandler, TcpServiceType.External, TcpSecurityType.Normal, new ClientTcpDispatcher(), ESConsts.ExternalHeartbeatInterval, ESConsts.ExternalHeartbeatTimeout, authenticationProvider, null); _mainBus.Subscribe<SystemMessage.SystemInit>(extTcpService); _mainBus.Subscribe<SystemMessage.SystemStart>(extTcpService); _mainBus.Subscribe<SystemMessage.BecomeShuttingDown>(extTcpService); // EXTERNAL SECURE TCP if (_nodeInfo.ExternalSecureTcp != null) { var extSecTcpService = new TcpService(_mainQueue, _nodeInfo.ExternalSecureTcp, _workersHandler, TcpServiceType.External, TcpSecurityType.Secure, new ClientTcpDispatcher(), ESConsts.ExternalHeartbeatInterval, ESConsts.ExternalHeartbeatTimeout, authenticationProvider, vNodeSettings.Certificate); _mainBus.Subscribe<SystemMessage.SystemInit>(extSecTcpService); _mainBus.Subscribe<SystemMessage.SystemStart>(extSecTcpService); _mainBus.Subscribe<SystemMessage.BecomeShuttingDown>(extSecTcpService); } // INTERNAL TCP var intTcpService = new TcpService(_mainQueue, _nodeInfo.InternalTcp, _workersHandler, TcpServiceType.Internal, TcpSecurityType.Normal, new InternalTcpDispatcher(), ESConsts.InternalHeartbeatInterval, ESConsts.InternalHeartbeatTimeout, authenticationProvider, null); _mainBus.Subscribe<SystemMessage.SystemInit>(intTcpService); _mainBus.Subscribe<SystemMessage.SystemStart>(intTcpService); _mainBus.Subscribe<SystemMessage.BecomeShuttingDown>(intTcpService); // INTERNAL SECURE TCP if (_nodeInfo.InternalSecureTcp != null) { var intSecTcpService = new TcpService(_mainQueue, _nodeInfo.InternalSecureTcp, _workersHandler, TcpServiceType.Internal, TcpSecurityType.Secure, new InternalTcpDispatcher(), ESConsts.InternalHeartbeatInterval, ESConsts.InternalHeartbeatTimeout, authenticationProvider, vNodeSettings.Certificate); _mainBus.Subscribe<SystemMessage.SystemInit>(intSecTcpService); _mainBus.Subscribe<SystemMessage.SystemStart>(intSecTcpService); _mainBus.Subscribe<SystemMessage.BecomeShuttingDown>(intSecTcpService); } } SubscribeWorkers(bus => { var tcpSendService = new TcpSendService(); // ReSharper disable RedundantTypeArgumentsOfMethod bus.Subscribe<TcpMessage.TcpSend>(tcpSendService); // ReSharper restore RedundantTypeArgumentsOfMethod }); var httpAuthenticationProviders = new List<HttpAuthenticationProvider> { new BasicHttpAuthenticationProvider(authenticationProvider), }; if (vNodeSettings.EnableTrustedAuth) httpAuthenticationProviders.Add(new TrustedHttpAuthenticationProvider()); httpAuthenticationProviders.Add(new AnonymousHttpAuthenticationProvider()); var httpPipe = new HttpMessagePipe(); var httpSendService = new HttpSendService(httpPipe, forwardRequests: true); _mainBus.Subscribe<SystemMessage.StateChangeMessage>(httpSendService); _mainBus.Subscribe(new WideningHandler<HttpMessage.SendOverHttp, Message>(_workersHandler)); SubscribeWorkers(bus => { bus.Subscribe<HttpMessage.HttpSend>(httpSendService); bus.Subscribe<HttpMessage.HttpSendPart>(httpSendService); bus.Subscribe<HttpMessage.HttpBeginSend>(httpSendService); bus.Subscribe<HttpMessage.HttpEndSend>(httpSendService); bus.Subscribe<HttpMessage.SendOverHttp>(httpSendService); }); var adminController = new AdminController(_mainQueue); var pingController = new PingController(); var statController = new StatController(monitoringQueue, _workersHandler); var atomController = new AtomController(httpSendService, _mainQueue, _workersHandler); var gossipController = new GossipController(_mainQueue, _workersHandler); var electController = new ElectController(_mainQueue); // HTTP SENDERS gossipController.SubscribeSenders(httpPipe); electController.SubscribeSenders(httpPipe); // EXTERNAL HTTP _externalHttpService = new HttpService(ServiceAccessibility.Public, _mainQueue, new TrieUriRouter(), _workersHandler, vNodeSettings.HttpPrefixes); _externalHttpService.SetupController(adminController); _externalHttpService.SetupController(pingController); _externalHttpService.SetupController(statController); _externalHttpService.SetupController(atomController); _externalHttpService.SetupController(gossipController); _mainBus.Subscribe<SystemMessage.SystemInit>(_externalHttpService); _mainBus.Subscribe<SystemMessage.BecomeShuttingDown>(_externalHttpService); _mainBus.Subscribe<HttpMessage.PurgeTimedOutRequests>(_externalHttpService); // INTERNAL HTTP _internalHttpService = new HttpService(ServiceAccessibility.Private, _mainQueue, new TrieUriRouter(), _workersHandler, _nodeInfo.InternalHttp.ToHttpUrl()); _internalHttpService.SetupController(adminController); _internalHttpService.SetupController(pingController); _internalHttpService.SetupController(statController); _internalHttpService.SetupController(atomController); _internalHttpService.SetupController(gossipController); _internalHttpService.SetupController(electController); // Authentication plugin HTTP vNodeSettings.AuthenticationProviderFactory.RegisterHttpControllers(_externalHttpService, _internalHttpService, httpSendService, _mainQueue, _workersHandler); _mainBus.Subscribe<SystemMessage.SystemInit>(_internalHttpService); _mainBus.Subscribe<SystemMessage.BecomeShuttingDown>(_internalHttpService); _mainBus.Subscribe<HttpMessage.PurgeTimedOutRequests>(_internalHttpService); SubscribeWorkers(bus => { HttpService.CreateAndSubscribePipeline(bus, httpAuthenticationProviders.ToArray()); }); // REQUEST FORWARDING var forwardingService = new RequestForwardingService(_mainQueue, forwardingProxy, TimeSpan.FromSeconds(1)); _mainBus.Subscribe<SystemMessage.SystemStart>(forwardingService); _mainBus.Subscribe<SystemMessage.RequestForwardingTimerTick>(forwardingService); _mainBus.Subscribe<ClientMessage.NotHandled>(forwardingService); _mainBus.Subscribe<ClientMessage.WriteEventsCompleted>(forwardingService); _mainBus.Subscribe<ClientMessage.TransactionStartCompleted>(forwardingService); _mainBus.Subscribe<ClientMessage.TransactionWriteCompleted>(forwardingService); _mainBus.Subscribe<ClientMessage.TransactionCommitCompleted>(forwardingService); _mainBus.Subscribe<ClientMessage.DeleteStreamCompleted>(forwardingService); // REQUEST MANAGEMENT var requestManagement = new RequestManagementService(_mainQueue, vNodeSettings.PrepareAckCount, vNodeSettings.CommitAckCount, vNodeSettings.PrepareTimeout, vNodeSettings.CommitTimeout); _mainBus.Subscribe<SystemMessage.SystemInit>(requestManagement); _mainBus.Subscribe<ClientMessage.WriteEvents>(requestManagement); _mainBus.Subscribe<ClientMessage.TransactionStart>(requestManagement); _mainBus.Subscribe<ClientMessage.TransactionWrite>(requestManagement); _mainBus.Subscribe<ClientMessage.TransactionCommit>(requestManagement); _mainBus.Subscribe<ClientMessage.DeleteStream>(requestManagement); _mainBus.Subscribe<StorageMessage.RequestCompleted>(requestManagement); _mainBus.Subscribe<StorageMessage.CheckStreamAccessCompleted>(requestManagement); _mainBus.Subscribe<StorageMessage.AlreadyCommitted>(requestManagement); _mainBus.Subscribe<StorageMessage.CommitAck>(requestManagement); _mainBus.Subscribe<StorageMessage.PrepareAck>(requestManagement); _mainBus.Subscribe<StorageMessage.WrongExpectedVersion>(requestManagement); _mainBus.Subscribe<StorageMessage.InvalidTransaction>(requestManagement); _mainBus.Subscribe<StorageMessage.StreamDeleted>(requestManagement); _mainBus.Subscribe<StorageMessage.RequestManagerTimerTick>(requestManagement); // SUBSCRIPTIONS var subscrBus = new InMemoryBus("SubscriptionsBus", true, TimeSpan.FromMilliseconds(50)); var subscrQueue = new QueuedHandlerThreadPool(subscrBus, "Subscriptions", false); _mainBus.Subscribe(subscrQueue.WidenFrom<SystemMessage.SystemStart, Message>()); _mainBus.Subscribe(subscrQueue.WidenFrom<SystemMessage.BecomeShuttingDown, Message>()); _mainBus.Subscribe(subscrQueue.WidenFrom<TcpMessage.ConnectionClosed, Message>()); _mainBus.Subscribe(subscrQueue.WidenFrom<ClientMessage.SubscribeToStream, Message>()); _mainBus.Subscribe(subscrQueue.WidenFrom<ClientMessage.UnsubscribeFromStream, Message>()); _mainBus.Subscribe(subscrQueue.WidenFrom<SubscriptionMessage.PollStream, Message>()); _mainBus.Subscribe(subscrQueue.WidenFrom<SubscriptionMessage.CheckPollTimeout, Message>()); _mainBus.Subscribe(subscrQueue.WidenFrom<StorageMessage.EventCommited, Message>()); var subscription = new SubscriptionsService(_mainQueue, subscrQueue, readIndex); subscrBus.Subscribe<SystemMessage.SystemStart>(subscription); subscrBus.Subscribe<SystemMessage.BecomeShuttingDown>(subscription); subscrBus.Subscribe<TcpMessage.ConnectionClosed>(subscription); subscrBus.Subscribe<ClientMessage.SubscribeToStream>(subscription); subscrBus.Subscribe<ClientMessage.UnsubscribeFromStream>(subscription); subscrBus.Subscribe<SubscriptionMessage.PollStream>(subscription); subscrBus.Subscribe<SubscriptionMessage.CheckPollTimeout>(subscription); subscrBus.Subscribe<StorageMessage.EventCommited>(subscription); // TIMER _timeProvider = new RealTimeProvider(); _timerService = new TimerService(new ThreadBasedScheduler(_timeProvider)); _mainBus.Subscribe<SystemMessage.BecomeShutdown>(_timerService); _mainBus.Subscribe<TimerMessage.Schedule>(_timerService); // MASTER REPLICATION var masterReplicationService = new MasterReplicationService(_mainQueue, _nodeInfo.InstanceId, db, _workersHandler, epochManager, vNodeSettings.ClusterNodeCount); _mainBus.Subscribe<SystemMessage.SystemStart>(masterReplicationService); _mainBus.Subscribe<SystemMessage.StateChangeMessage>(masterReplicationService); _mainBus.Subscribe<ReplicationMessage.ReplicaSubscriptionRequest>(masterReplicationService); _mainBus.Subscribe<ReplicationMessage.ReplicaLogPositionAck>(masterReplicationService); // REPLICA REPLICATION var replicaService = new ReplicaService(_mainQueue, db, epochManager, _workersHandler, authenticationProvider, _nodeInfo, vNodeSettings.UseSsl, vNodeSettings.SslTargetHost, vNodeSettings.SslValidateServer); _mainBus.Subscribe<SystemMessage.StateChangeMessage>(replicaService); _mainBus.Subscribe<ReplicationMessage.ReconnectToMaster>(replicaService); _mainBus.Subscribe<ReplicationMessage.SubscribeToMaster>(replicaService); _mainBus.Subscribe<ReplicationMessage.AckLogPosition>(replicaService); _mainBus.Subscribe<StorageMessage.PrepareAck>(replicaService); _mainBus.Subscribe<StorageMessage.CommitAck>(replicaService); _mainBus.Subscribe<ClientMessage.TcpForwardMessage>(replicaService); // ELECTIONS var electionsService = new ElectionsService(_mainQueue, _nodeInfo, vNodeSettings.ClusterNodeCount, db.Config.WriterCheckpoint, db.Config.ChaserCheckpoint, epochManager, () => readIndex.LastCommitPosition, vNodeSettings.NodePriority); electionsService.SubscribeMessages(_mainBus); // GOSSIP var gossip = new NodeGossipService(_mainQueue, gossipSeedSource, _nodeInfo, db.Config.WriterCheckpoint, db.Config.ChaserCheckpoint, epochManager, () => readIndex.LastCommitPosition, vNodeSettings.NodePriority); _mainBus.Subscribe<SystemMessage.SystemInit>(gossip); _mainBus.Subscribe<GossipMessage.RetrieveGossipSeedSources>(gossip); _mainBus.Subscribe<GossipMessage.GotGossipSeedSources>(gossip); _mainBus.Subscribe<GossipMessage.Gossip>(gossip); _mainBus.Subscribe<GossipMessage.GossipReceived>(gossip); _mainBus.Subscribe<SystemMessage.StateChangeMessage>(gossip); _mainBus.Subscribe<GossipMessage.GossipSendFailed>(gossip); _mainBus.Subscribe<SystemMessage.VNodeConnectionEstablished>(gossip); _mainBus.Subscribe<SystemMessage.VNodeConnectionLost>(gossip); _workersHandler.Start(); _mainQueue.Start(); monitoringQueue.Start(); subscrQueue.Start(); if (subsystems != null) { foreach (var subsystem in subsystems) { subsystem.Register(db, _mainQueue, _mainBus, _timerService, _timeProvider, httpSendService, new[] { _internalHttpService, _externalHttpService }, _workersHandler); } } }
public SingleVNode(TFChunkDb db, SingleVNodeSettings vNodeSettings, bool dbVerifyHashes, int memTableEntryCount = ESConsts.MemTableEntryCount) { Ensure.NotNull(db, "db"); Ensure.NotNull(vNodeSettings, "vNodeSettings"); db.OpenVerifyAndClean(dbVerifyHashes); _tcpEndPoint = vNodeSettings.ExternalTcpEndPoint; _httpEndPoint = vNodeSettings.ExternalHttpEndPoint; _mainBus = new InMemoryBus("MainBus"); _controller = new SingleVNodeController(Bus, _httpEndPoint); _mainQueue = new QueuedHandler(_controller, "MainQueue"); _controller.SetMainQueue(MainQueue); //MONITORING var monitoringInnerBus = new InMemoryBus("MonitoringInnerBus", watchSlowMsg: false); var monitoringRequestBus = new InMemoryBus("MonitoringRequestBus", watchSlowMsg: false); var monitoringQueue = new QueuedHandler(monitoringInnerBus, "MonitoringQueue", true, TimeSpan.FromMilliseconds(100)); var monitoring = new MonitoringService(monitoringQueue, monitoringRequestBus, MainQueue, db.Config.WriterCheckpoint, db.Config.Path, vNodeSettings.StatsPeriod, _httpEndPoint, vNodeSettings.StatsStorage); Bus.Subscribe(monitoringQueue.WidenFrom<SystemMessage.SystemInit, Message>()); Bus.Subscribe(monitoringQueue.WidenFrom<SystemMessage.StateChangeMessage, Message>()); Bus.Subscribe(monitoringQueue.WidenFrom<SystemMessage.BecomeShuttingDown, Message>()); Bus.Subscribe(monitoringQueue.WidenFrom<ClientMessage.CreateStreamCompleted, Message>()); monitoringInnerBus.Subscribe<SystemMessage.SystemInit>(monitoring); monitoringInnerBus.Subscribe<SystemMessage.StateChangeMessage>(monitoring); monitoringInnerBus.Subscribe<SystemMessage.BecomeShuttingDown>(monitoring); monitoringInnerBus.Subscribe<ClientMessage.CreateStreamCompleted>(monitoring); monitoringInnerBus.Subscribe<MonitoringMessage.GetFreshStats>(monitoring); //STORAGE SUBSYSTEM var indexPath = Path.Combine(db.Config.Path, "index"); var tableIndex = new TableIndex(indexPath, () => new HashListMemTable(maxSize: memTableEntryCount * 2), maxSizeForMemory: memTableEntryCount, maxTablesPerLevel: 2); var readIndex = new ReadIndex(_mainQueue, ESConsts.ReadIndexReaderCount, () => new TFChunkSequentialReader(db, db.Config.WriterCheckpoint, 0), () => new TFChunkReader(db, db.Config.WriterCheckpoint), tableIndex, new XXHashUnsafe(), new LRUCache<string, StreamCacheInfo>(ESConsts.MetadataCacheCapacity)); var writer = new TFChunkWriter(db); new StorageWriterService(_mainQueue, _mainBus, writer, readIndex); // subscribes internally var storageReader = new StorageReaderService(_mainQueue, _mainBus, readIndex, ESConsts.StorageReaderHandlerCount, db.Config.WriterCheckpoint); _mainBus.Subscribe<SystemMessage.SystemInit>(storageReader); _mainBus.Subscribe<SystemMessage.BecomeShuttingDown>(storageReader); _mainBus.Subscribe<SystemMessage.BecomeShutdown>(storageReader); monitoringRequestBus.Subscribe<MonitoringMessage.InternalStatsRequest>(storageReader); var chaser = new TFChunkChaser(db, db.Config.WriterCheckpoint, db.Config.ChaserCheckpoint); var storageChaser = new StorageChaser(_mainQueue, db.Config.WriterCheckpoint, chaser, readIndex, _tcpEndPoint); _mainBus.Subscribe<SystemMessage.SystemInit>(storageChaser); _mainBus.Subscribe<SystemMessage.SystemStart>(storageChaser); _mainBus.Subscribe<SystemMessage.BecomeShuttingDown>(storageChaser); var storageScavenger = new StorageScavenger(db, readIndex); _mainBus.Subscribe<SystemMessage.ScavengeDatabase>(storageScavenger); // NETWORK SEND _networkSendService = new NetworkSendService(tcpQueueCount: vNodeSettings.TcpSendingThreads, httpQueueCount: vNodeSettings.HttpSendingThreads); //TCP var tcpService = new TcpService(MainQueue, _tcpEndPoint, _networkSendService); Bus.Subscribe<SystemMessage.SystemInit>(tcpService); Bus.Subscribe<SystemMessage.SystemStart>(tcpService); Bus.Subscribe<SystemMessage.BecomeShuttingDown>(tcpService); //HTTP _httpService = new HttpService(ServiceAccessibility.Private, MainQueue, vNodeSettings.HttpReceivingThreads, vNodeSettings.HttpPrefixes); Bus.Subscribe<SystemMessage.SystemInit>(HttpService); Bus.Subscribe<SystemMessage.BecomeShuttingDown>(HttpService); Bus.Subscribe<HttpMessage.SendOverHttp>(HttpService); Bus.Subscribe<HttpMessage.PurgeTimedOutRequests>(HttpService); HttpService.SetupController(new AdminController(MainQueue)); HttpService.SetupController(new PingController()); HttpService.SetupController(new StatController(monitoringQueue, _networkSendService)); HttpService.SetupController(new ReadEventDataController(MainQueue, _networkSendService)); HttpService.SetupController(new AtomController(MainQueue, _networkSendService)); HttpService.SetupController(new WebSiteController(MainQueue)); //REQUEST MANAGEMENT var requestManagement = new RequestManagementService(MainQueue, 1, 1); Bus.Subscribe<StorageMessage.CreateStreamRequestCreated>(requestManagement); Bus.Subscribe<StorageMessage.WriteRequestCreated>(requestManagement); Bus.Subscribe<StorageMessage.TransactionStartRequestCreated>(requestManagement); Bus.Subscribe<StorageMessage.TransactionWriteRequestCreated>(requestManagement); Bus.Subscribe<StorageMessage.TransactionCommitRequestCreated>(requestManagement); Bus.Subscribe<StorageMessage.DeleteStreamRequestCreated>(requestManagement); Bus.Subscribe<StorageMessage.RequestCompleted>(requestManagement); Bus.Subscribe<StorageMessage.AlreadyCommitted>(requestManagement); Bus.Subscribe<StorageMessage.CommitAck>(requestManagement); Bus.Subscribe<StorageMessage.PrepareAck>(requestManagement); Bus.Subscribe<StorageMessage.WrongExpectedVersion>(requestManagement); Bus.Subscribe<StorageMessage.InvalidTransaction>(requestManagement); Bus.Subscribe<StorageMessage.StreamDeleted>(requestManagement); Bus.Subscribe<StorageMessage.PreparePhaseTimeout>(requestManagement); Bus.Subscribe<StorageMessage.CommitPhaseTimeout>(requestManagement); new SubscriptionsService(_mainBus, readIndex); // subcribes internally //TIMER _timerService = new TimerService(new ThreadBasedScheduler(new RealTimeProvider())); Bus.Subscribe<TimerMessage.Schedule>(TimerService); monitoringQueue.Start(); MainQueue.Start(); }
public override void TestFixtureSetUp() { base.TestFixtureSetUp(); WriterCheckpoint = new InMemoryCheckpoint(0); var chaserchk = new InMemoryCheckpoint(Checkpoint.Chaser, 0); Db = new TFChunkDb(new TFChunkDbConfig(PathName, new VersionedPatternFileNamingStrategy(PathName, "chunk-"), 10000, 0, WriterCheckpoint, new[] {chaserchk})); Db.OpenVerifyAndClean(); // create db Writer = new TFChunkWriter(Db); Writer.Open(); WriteTestScenario(); Writer.Close(); Writer = null; WriterCheckpoint.Flush(); chaserchk.Write(WriterCheckpoint.Read()); chaserchk.Flush(); TableIndex = new TableIndex(Path.Combine(PathName, "index"), () => new HashListMemTable(), _maxEntriesInMemTable); TableIndex.Initialize(); var reader = new TFChunkReader(Db, Db.Config.WriterCheckpoint); ReadIndex = new ReadIndex(new NoopPublisher(), 2, () => new TFChunkSequentialReader(Db, Db.Config.WriterCheckpoint, 0), () => reader, TableIndex, new ByLengthHasher()); ReadIndex.Build(); }
public void try_read_returns_record_when_writerchecksum_equal() { var writerchk = new InMemoryCheckpoint(0); var chaserchk = new InMemoryCheckpoint(Checkpoint.Chaser, 0); var db = new TFChunkDb(new TFChunkDbConfig(PathName, new PrefixFileNamingStrategy(PathName, "prefix.tf"), 10000, 0, writerchk, chaserchk, new[] {chaserchk})); db.OpenVerifyAndClean(); var recordToWrite = new PrepareLogRecord(logPosition: 0, correlationId: _correlationId, eventId: _eventId, transactionPosition: 0, transactionOffset: 0, eventStreamId: "WorldEnding", expectedVersion: 1234, timeStamp: new DateTime(2012, 12, 21), flags: PrepareFlags.None, eventType: "type", data: new byte[] { 1, 2, 3, 4, 5 }, metadata: new byte[] { 7, 17 }); var writer = new TFChunkWriter(db); writer.Open(); long pos; Assert.IsTrue(writer.Write(recordToWrite, out pos)); writer.Close(); writerchk.Write(recordToWrite.GetSizeWithLengthPrefixAndSuffix()); var chaser = new TFChunkChaser(db, writerchk, chaserchk); chaser.Open(); LogRecord record; var readRecord = chaser.TryReadNext(out record); chaser.Close(); Assert.IsTrue(readRecord); Assert.AreEqual(record.GetSizeWithLengthPrefixAndSuffix(), chaserchk.Read()); Assert.AreEqual(recordToWrite, record); db.Close(); }