Beispiel #1
0
        protected override void Create()
        {
            base.Create();
            var db = this.TfDb;

            _coreInputBus = new InMemoryBus("bus");
            _coreQueue    = new QueuedHandler(_coreInputBus, "ProjectionCoreQueue");

            _readerInputBus = new InMemoryBus("Reader Input");

            _projectionNode = new ProjectionWorkerNode(db, _coreQueue, Node.HttpService);
            _projectionNode.SetupMessaging(_coreInputBus, _readerInputBus);

            _forwarder = new RequestResponseQueueForwarder(inputQueue: _coreQueue, externalRequestQueue: Node.MainQueue);
            // forwarded messages
            _projectionNode.CoreOutput.Subscribe <ClientMessage.ReadEvent>(_forwarder);
            _projectionNode.CoreOutput.Subscribe <ClientMessage.ReadEventsBackwards>(_forwarder);
            _projectionNode.CoreOutput.Subscribe <ClientMessage.ReadEventsForward>(_forwarder);
            _projectionNode.CoreOutput.Subscribe <ClientMessage.ReadEventsFromTF>(_forwarder);
            _projectionNode.CoreOutput.Subscribe <ClientMessage.WriteEvents>(_forwarder);
            _coreInputBus.Subscribe(new UnwrapEnvelopeHandler());

            Node.Bus.Subscribe(Forwarder.Create <SystemMessage.BecomeShuttingDown>(_coreQueue));
            Node.Bus.Subscribe(Forwarder.Create <SystemMessage.SystemInit>(_coreQueue));
            Node.Bus.Subscribe(Forwarder.Create <SystemMessage.SystemStart>(_coreQueue));

            _projectionNode.CoreOutput.Subscribe(Node.TimerService);
            _coreInputBus.Subscribe <SystemMessage.SystemStart>(this);
        }
Beispiel #2
0
        private static void SubscribeOutputBus(
            StandardComponents standardComponents,
            ProjectionsStandardComponents projectionsStandardComponents,
            RequestResponseQueueForwarder forwarder)
        {
            var managerOutput = projectionsStandardComponents.MasterOutputBus;

            managerOutput.Subscribe <ClientMessage.ReadEvent>(forwarder);
            managerOutput.Subscribe <ClientMessage.ReadStreamEventsBackward>(forwarder);
            managerOutput.Subscribe <ClientMessage.ReadStreamEventsForward>(forwarder);
            managerOutput.Subscribe <ClientMessage.WriteEvents>(forwarder);
            managerOutput.Subscribe <ClientMessage.DeleteStream>(forwarder);
            managerOutput.Subscribe(
                Forwarder.Create <ProjectionManagementMessage.RequestSystemProjections>(standardComponents.MainQueue));
            managerOutput.Subscribe(Forwarder.Create <Message>(projectionsStandardComponents.MasterInputQueue));

            managerOutput.Subscribe <TimerMessage.Schedule>(standardComponents.TimerService);
            managerOutput.Subscribe(Forwarder.Create <AwakeServiceMessage.SubscribeAwake>(standardComponents.MainQueue));
            managerOutput.Subscribe(
                Forwarder.Create <AwakeServiceMessage.UnsubscribeAwake>(standardComponents.MainQueue));

            // self forward all
            standardComponents.MainBus.Subscribe(
                Forwarder.Create <SystemMessage.StateChangeMessage>(projectionsStandardComponents.MasterInputQueue));
            standardComponents.MainBus.Subscribe(
                Forwarder.Create <SystemMessage.SystemReady>(projectionsStandardComponents.MasterInputQueue));
            projectionsStandardComponents.MasterMainBus.Subscribe(new UnwrapEnvelopeHandler());
        }
        public static void CreateManagerService(
            StandardComponents standardComponents,
            ProjectionsStandardComponents projectionsStandardComponents,
            IDictionary <Guid, IPublisher> queues,
            TimeSpan projectionQueryExpiry)
        {
            IQueuedHandler inputQueue   = projectionsStandardComponents.MasterInputQueue;
            InMemoryBus    outputBus    = projectionsStandardComponents.MasterOutputBus;
            var            ioDispatcher = new IODispatcher(outputBus, new PublishEnvelope(inputQueue));

            var projectionsController = new ProjectionsController(
                standardComponents.HttpForwarder,
                inputQueue,
                standardComponents.NetworkSendService);

            var forwarder = new RequestResponseQueueForwarder(
                inputQueue: projectionsStandardComponents.MasterInputQueue,
                externalRequestQueue: standardComponents.MainQueue);

            if (projectionsStandardComponents.RunProjections != ProjectionType.None)
            {
                foreach (var httpService in standardComponents.HttpServices)
                {
                    httpService.SetupController(projectionsController);
                }
            }

            var commandWriter = new MultiStreamMessageWriter(ioDispatcher);
            var projectionManagerCommandWriter  = new ProjectionManagerCommandWriter(commandWriter);
            var projectionManagerResponseReader = new ProjectionManagerResponseReader(outputBus, ioDispatcher,
                                                                                      queues.Count);

            var projectionManager = new ProjectionManager(
                inputQueue,
                outputBus,
                queues,
                new RealTimeProvider(),
                projectionsStandardComponents.RunProjections,
                ioDispatcher,
                projectionQueryExpiry);

            SubscribeMainBus(
                projectionsStandardComponents.MasterMainBus,
                projectionManager,
                projectionsStandardComponents.RunProjections,
                projectionManagerResponseReader,
                ioDispatcher,
                projectionManagerCommandWriter);


            SubscribeOutputBus(standardComponents, projectionsStandardComponents, forwarder);
        }
        public static void CreateManagerService(
            StandardComponents standardComponents,
            ProjectionsStandardComponents projectionsStandardComponents,
            IDictionary<Guid, IPublisher> queues)
        {
            QueuedHandler inputQueue = projectionsStandardComponents.MasterInputQueue;
            InMemoryBus outputBus = projectionsStandardComponents.MasterOutputBus;
            var ioDispatcher = new IODispatcher(outputBus, new PublishEnvelope(inputQueue));

            var projectionsController = new ProjectionsController(
                standardComponents.HttpForwarder,
                inputQueue,
                standardComponents.NetworkSendService);

            var forwarder = new RequestResponseQueueForwarder(
                inputQueue: projectionsStandardComponents.MasterInputQueue,
                externalRequestQueue: standardComponents.MainQueue);

            if (projectionsStandardComponents.RunProjections != ProjectionType.None)
            {
                foreach (var httpService in standardComponents.HttpServices)
                {
                    httpService.SetupController(projectionsController);
                }
            }

            var commandWriter = new MultiStreamMessageWriter(ioDispatcher);
            var projectionManagerCommandWriter = new ProjectionManagerCommandWriter(commandWriter);
            var projectionManagerResponseReader = new ProjectionManagerResponseReader(outputBus, ioDispatcher, queues.Count);

            var projectionManager = new ProjectionManager(
                inputQueue,
                outputBus,
                queues,
                new RealTimeProvider(),
                projectionsStandardComponents.RunProjections,
                ioDispatcher);

            SubscribeMainBus(
                projectionsStandardComponents.MasterMainBus,
                projectionManager,
                projectionsStandardComponents.RunProjections,
                projectionManagerResponseReader,
                ioDispatcher,
                projectionManagerCommandWriter);


            SubscribeOutputBus(standardComponents, projectionsStandardComponents, forwarder);
        }
        private static void SubscribeOutputBus(
            StandardComponents standardComponents,
            ProjectionsStandardComponents projectionsStandardComponents,
            RequestResponseQueueForwarder forwarder,
            IODispatcher ioDispatcher)
        {
            var managerOutput = projectionsStandardComponents.LeaderOutputBus;

            managerOutput.Subscribe <ClientMessage.ReadEvent>(forwarder);
            managerOutput.Subscribe <ClientMessage.ReadStreamEventsBackward>(forwarder);
            managerOutput.Subscribe <ClientMessage.ReadStreamEventsForward>(forwarder);
            managerOutput.Subscribe <ClientMessage.WriteEvents>(forwarder);
            managerOutput.Subscribe <ClientMessage.DeleteStream>(forwarder);
            managerOutput.Subscribe(Forwarder.Create <Message>(projectionsStandardComponents.LeaderInputQueue));
            managerOutput.Subscribe <ClientMessage.NotHandled>(ioDispatcher);

            managerOutput.Subscribe <TimerMessage.Schedule>(standardComponents.TimerService);
            managerOutput.Subscribe(Forwarder.Create <AwakeServiceMessage.SubscribeAwake>(standardComponents.MainQueue));
            managerOutput.Subscribe(
                Forwarder.Create <AwakeServiceMessage.UnsubscribeAwake>(standardComponents.MainQueue));
            managerOutput.Subscribe <SystemMessage.SubSystemInitialized>(forwarder);

            // self forward all
            standardComponents.MainBus.Subscribe(
                Forwarder.Create <SystemMessage.StateChangeMessage>(projectionsStandardComponents.LeaderInputQueue));
            standardComponents.MainBus.Subscribe(
                Forwarder.Create <SystemMessage.SystemCoreReady>(projectionsStandardComponents.LeaderInputQueue));
            standardComponents.MainBus.Subscribe(
                Forwarder.Create <SystemMessage.EpochWritten>(projectionsStandardComponents.LeaderInputQueue));
            standardComponents.MainBus.Subscribe(
                Forwarder.Create <ProjectionCoreServiceMessage.SubComponentStarted>(projectionsStandardComponents
                                                                                    .LeaderInputQueue));
            standardComponents.MainBus.Subscribe(
                Forwarder.Create <ProjectionCoreServiceMessage.SubComponentStopped>(projectionsStandardComponents
                                                                                    .LeaderInputQueue));
            projectionsStandardComponents.LeaderMainBus.Subscribe(new UnwrapEnvelopeHandler());
        }
        public static Dictionary<Guid, QueuedHandler> CreateCoreWorkers(
            StandardComponents standardComponents,
            ProjectionsStandardComponents projectionsStandardComponents)
        {
            var coreTimeoutSchedulers =
                CreateTimeoutSchedulers(projectionsStandardComponents.ProjectionWorkerThreadCount);

            var coreQueues = new Dictionary<Guid, QueuedHandler>();
            while (coreQueues.Count < projectionsStandardComponents.ProjectionWorkerThreadCount)
            {
                var coreInputBus = new InMemoryBus("bus");
                var coreQueue = new QueuedHandler(
                    coreInputBus,
                    "Projection Core #" + coreQueues.Count,
                    groupName: "Projection Core");
                var workerId = Guid.NewGuid();
                var projectionNode = new ProjectionWorkerNode(
                    workerId,
                    standardComponents.Db,
                    coreQueue,
                    standardComponents.TimeProvider,
                    coreTimeoutSchedulers[coreQueues.Count],
                    projectionsStandardComponents.RunProjections);
                projectionNode.SetupMessaging(coreInputBus);

                var forwarder = new RequestResponseQueueForwarder(
                    inputQueue: coreQueue,
                    externalRequestQueue: standardComponents.MainQueue);
                // forwarded messages
                var coreOutput = projectionNode.CoreOutput;
                coreOutput.Subscribe<ClientMessage.ReadEvent>(forwarder);
                coreOutput.Subscribe<ClientMessage.ReadStreamEventsBackward>(forwarder);
                coreOutput.Subscribe<ClientMessage.ReadStreamEventsForward>(forwarder);
                coreOutput.Subscribe<ClientMessage.ReadAllEventsForward>(forwarder);
                coreOutput.Subscribe<ClientMessage.WriteEvents>(forwarder);
                coreOutput.Subscribe<ClientMessage.DeleteStream>(forwarder);


                if (projectionsStandardComponents.RunProjections >= ProjectionType.System)
                {
                    var slaveProjectionResponseWriter = projectionNode.SlaveProjectionResponseWriter;
                    coreOutput.Subscribe<PartitionMeasuredOutput>(slaveProjectionResponseWriter);
                    coreOutput.Subscribe<PartitionProcessingProgressOutput>(slaveProjectionResponseWriter);
                    coreOutput.Subscribe<PartitionProcessingResultOutput>(slaveProjectionResponseWriter);
                    coreOutput.Subscribe<ReaderSubscriptionManagement.SpoolStreamReading>(slaveProjectionResponseWriter);


                    coreOutput.Subscribe(
                        Forwarder.Create<AwakeServiceMessage.SubscribeAwake>(standardComponents.MainQueue));
                    coreOutput.Subscribe(
                        Forwarder.Create<AwakeServiceMessage.UnsubscribeAwake>(standardComponents.MainQueue));
                }
                coreOutput.Subscribe<TimerMessage.Schedule>(standardComponents.TimerService);


                coreOutput.Subscribe(Forwarder.Create<Message>(coreQueue)); // forward all

                coreInputBus.Subscribe(new UnwrapEnvelopeHandler());

                coreQueues.Add(workerId, coreQueue);
            }
            var queues = coreQueues.Select(v => v.Value).Cast<IPublisher>().ToArray();
            var coordinator = new ProjectionCoreCoordinator(
                projectionsStandardComponents.RunProjections,
                coreTimeoutSchedulers,
                queues,
                projectionsStandardComponents.MasterOutputBus,
                new PublishEnvelope(projectionsStandardComponents.MasterInputQueue, crossThread: true));

            coordinator.SetupMessaging(projectionsStandardComponents.MasterMainBus);
            projectionsStandardComponents.MasterMainBus.Subscribe(
                Forwarder.CreateBalancing<FeedReaderMessage.ReadPage>(coreQueues.Values.Cast<IPublisher>().ToArray()));
            return coreQueues;
        }
        private void SetUpCoreServices(
            Guid workerId,
            IBus bus,
            IPublisher inputQueue,
            InMemoryBus output_,
            ISingletonTimeoutScheduler timeoutScheduler)
        {
            var output = (output_ ?? inputQueue);
            ICheckpoint writerCheckpoint = new InMemoryCheckpoint(1000);
            var readerService = new EventReaderCoreService(
                output,
                _ioDispatcher,
                10,
                writerCheckpoint,
                runHeadingReader: true);
            _subscriptionDispatcher = new ReaderSubscriptionDispatcher(inputQueue);
            var spoolProcessingResponseDispatcher = new SpooledStreamReadingDispatcher(GetInputQueue());

            bus.Subscribe(
                _subscriptionDispatcher.CreateSubscriber<EventReaderSubscriptionMessage.CheckpointSuggested>());
            bus.Subscribe(
                _subscriptionDispatcher.CreateSubscriber<EventReaderSubscriptionMessage.CommittedEventReceived>());
            bus.Subscribe(_subscriptionDispatcher.CreateSubscriber<EventReaderSubscriptionMessage.EofReached>());
            bus.Subscribe(
                _subscriptionDispatcher.CreateSubscriber<EventReaderSubscriptionMessage.PartitionEofReached>());
            bus.Subscribe(_subscriptionDispatcher.CreateSubscriber<EventReaderSubscriptionMessage.PartitionMeasured>());
            bus.Subscribe(_subscriptionDispatcher.CreateSubscriber<EventReaderSubscriptionMessage.PartitionDeleted>());
            bus.Subscribe(_subscriptionDispatcher.CreateSubscriber<EventReaderSubscriptionMessage.ProgressChanged>());
            bus.Subscribe(
                _subscriptionDispatcher.CreateSubscriber<EventReaderSubscriptionMessage.SubscriptionStarted>());
            bus.Subscribe(_subscriptionDispatcher.CreateSubscriber<EventReaderSubscriptionMessage.NotAuthorized>());
            bus.Subscribe(
                _subscriptionDispatcher.CreateSubscriber<EventReaderSubscriptionMessage.ReaderAssignedReader>());
            bus.Subscribe(spoolProcessingResponseDispatcher.CreateSubscriber<PartitionProcessingResult>());

            var ioDispatcher = new IODispatcher(output, new PublishEnvelope(inputQueue));
//            var coreServiceCommandReader = new ProjectionCoreServiceCommandReader(
//                output,
//                ioDispatcher,
//                workerId.ToString("N"));

            var coreService = new ProjectionCoreService(
                workerId,
                inputQueue,
                output,
                _subscriptionDispatcher,
                _timeProvider,
                ioDispatcher,
                spoolProcessingResponseDispatcher,
                timeoutScheduler);

            bus.Subscribe<CoreProjectionManagementMessage.CreateAndPrepare>(coreService);
            bus.Subscribe<CoreProjectionManagementMessage.CreatePrepared>(coreService);
            bus.Subscribe<CoreProjectionManagementMessage.CreateAndPrepareSlave>(coreService);
            bus.Subscribe<CoreProjectionManagementMessage.Dispose>(coreService);
            bus.Subscribe<CoreProjectionManagementMessage.Start>(coreService);
            bus.Subscribe<CoreProjectionManagementMessage.LoadStopped>(coreService);
            bus.Subscribe<CoreProjectionManagementMessage.Stop>(coreService);
            bus.Subscribe<CoreProjectionManagementMessage.Kill>(coreService);
            bus.Subscribe<CoreProjectionManagementMessage.GetState>(coreService);
            bus.Subscribe<CoreProjectionManagementMessage.GetResult>(coreService);
            bus.Subscribe<CoreProjectionProcessingMessage.CheckpointCompleted>(coreService);
            bus.Subscribe<CoreProjectionProcessingMessage.CheckpointLoaded>(coreService);
            bus.Subscribe<CoreProjectionProcessingMessage.PrerecordedEventsLoaded>(coreService);
            bus.Subscribe<CoreProjectionProcessingMessage.RestartRequested>(coreService);
            bus.Subscribe<CoreProjectionProcessingMessage.Failed>(coreService);
            bus.Subscribe<ClientMessage.ReadStreamEventsForwardCompleted>(ioDispatcher.ForwardReader);
            bus.Subscribe<ClientMessage.ReadStreamEventsBackwardCompleted>(ioDispatcher.BackwardReader);
            bus.Subscribe<ClientMessage.WriteEventsCompleted>(ioDispatcher.Writer);
            bus.Subscribe<ClientMessage.DeleteStreamCompleted>(ioDispatcher.StreamDeleter);
            bus.Subscribe<IODispatcherDelayedMessage>(ioDispatcher.Awaker);
            bus.Subscribe<IODispatcherDelayedMessage>(ioDispatcher);
            bus.Subscribe<ProjectionCoreServiceMessage.StartCore>(coreService);
            bus.Subscribe<ProjectionCoreServiceMessage.StopCore>(coreService);
            bus.Subscribe<ReaderCoreServiceMessage.StartReader>(readerService);
            bus.Subscribe<ReaderCoreServiceMessage.StopReader>(readerService);
            bus.Subscribe<ProjectionCoreServiceMessage.CoreTick>(coreService);
            bus.Subscribe<ProjectionManagementMessage.SlaveProjectionsStarted>(coreService);
            bus.Subscribe<ReaderCoreServiceMessage.ReaderTick>(readerService);
            bus.Subscribe<ReaderSubscriptionMessage.CommittedEventDistributed>(readerService);
            bus.Subscribe<ReaderSubscriptionMessage.EventReaderEof>(readerService);
            bus.Subscribe<ReaderSubscriptionMessage.EventReaderPartitionEof>(readerService);
            bus.Subscribe<ReaderSubscriptionMessage.EventReaderPartitionDeleted>(readerService);
            bus.Subscribe<ReaderSubscriptionMessage.EventReaderPartitionMeasured>(readerService);
            bus.Subscribe<ReaderSubscriptionMessage.EventReaderNotAuthorized>(readerService);
            bus.Subscribe<ReaderSubscriptionMessage.EventReaderIdle>(readerService);
            bus.Subscribe<ReaderSubscriptionMessage.EventReaderStarting>(readerService);
            bus.Subscribe<ReaderSubscriptionManagement.Pause>(readerService);
            bus.Subscribe<ReaderSubscriptionManagement.Resume>(readerService);
            bus.Subscribe<ReaderSubscriptionManagement.Subscribe>(readerService);
            bus.Subscribe<ReaderSubscriptionManagement.Unsubscribe>(readerService);
            bus.Subscribe<ReaderSubscriptionManagement.SpoolStreamReadingCore>(readerService);
            bus.Subscribe<ReaderSubscriptionManagement.CompleteSpooledStreamReading>(readerService);

            if (output_ != null)
            {
                bus.Subscribe(new UnwrapEnvelopeHandler());
                output_.Subscribe(Forwarder.Create<CoreProjectionStatusMessage.StateReport>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create<CoreProjectionStatusMessage.ResultReport>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create<CoreProjectionStatusMessage.StatisticsReport>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create<CoreProjectionStatusMessage.Started>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create<CoreProjectionStatusMessage.Stopped>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create<CoreProjectionStatusMessage.Faulted>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create<CoreProjectionStatusMessage.Prepared>(GetInputQueue()));
                output_.Subscribe(
                    Forwarder.Create<CoreProjectionManagementMessage.SlaveProjectionReaderAssigned>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create<CoreProjectionStatusMessage.ProjectionWorkerStarted>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create<ProjectionManagementMessage.Command.ControlMessage>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create<AwakeServiceMessage.SubscribeAwake>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create<AwakeServiceMessage.UnsubscribeAwake>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create<PartitionProcessingResultBase>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create<ReaderSubscriptionManagement.SpoolStreamReading>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create<PartitionProcessingResultOutputBase>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create<Message>(inputQueue)); // forward all

                var forwarder = new RequestResponseQueueForwarder(
                    inputQueue: inputQueue,
                    externalRequestQueue: GetInputQueue());
                // forwarded messages
                output_.Subscribe<ClientMessage.ReadEvent>(forwarder);
                output_.Subscribe<ClientMessage.ReadStreamEventsBackward>(forwarder);
                output_.Subscribe<ClientMessage.ReadStreamEventsForward>(forwarder);
                output_.Subscribe<ClientMessage.ReadAllEventsForward>(forwarder);
                output_.Subscribe<ClientMessage.WriteEvents>(forwarder);

            }
        }
Beispiel #8
0
        private void SetupMessaging(
            TFChunkDb db, QueuedHandler mainQueue, ISubscriber mainBus, TimerService timerService, ITimeProvider timeProvider,
            IHttpForwarder httpForwarder, HttpService[] httpServices, IPublisher networkSendQueue, RunProjections runProjections)
        {
            _coreQueues = new List<QueuedHandler>();
            _managerInputBus = new InMemoryBus("manager input bus");
            _managerInputQueue = new QueuedHandler(_managerInputBus, "Projections Master");
            while (_coreQueues.Count < _projectionWorkerThreadCount)
            {
                var coreInputBus = new InMemoryBus("bus");
                var coreQueue = new QueuedHandler(
                    coreInputBus, "Projection Core #" + _coreQueues.Count, groupName: "Projection Core");
                var projectionNode = new ProjectionWorkerNode(db, coreQueue, timeProvider, runProjections);
                projectionNode.SetupMessaging(coreInputBus);


                var forwarder = new RequestResponseQueueForwarder(
                    inputQueue: coreQueue, externalRequestQueue: mainQueue);
                // forwarded messages
                projectionNode.CoreOutput.Subscribe<ClientMessage.ReadEvent>(forwarder);
                projectionNode.CoreOutput.Subscribe<ClientMessage.ReadStreamEventsBackward>(forwarder);
                projectionNode.CoreOutput.Subscribe<ClientMessage.ReadStreamEventsForward>(forwarder);
                projectionNode.CoreOutput.Subscribe<ClientMessage.ReadAllEventsForward>(forwarder);
                projectionNode.CoreOutput.Subscribe<ClientMessage.WriteEvents>(forwarder);


                if (runProjections >= RunProjections.System)
                {
                    projectionNode.CoreOutput.Subscribe(
                        Forwarder.Create<CoreProjectionManagementMessage.StateReport>(_managerInputQueue));
                    projectionNode.CoreOutput.Subscribe(
                        Forwarder.Create<CoreProjectionManagementMessage.ResultReport>(_managerInputQueue));
                    projectionNode.CoreOutput.Subscribe(
                        Forwarder.Create<CoreProjectionManagementMessage.StatisticsReport>(_managerInputQueue));
                    projectionNode.CoreOutput.Subscribe(
                        Forwarder.Create<CoreProjectionManagementMessage.Started>(_managerInputQueue));
                    projectionNode.CoreOutput.Subscribe(
                        Forwarder.Create<CoreProjectionManagementMessage.Stopped>(_managerInputQueue));
                    projectionNode.CoreOutput.Subscribe(
                        Forwarder.Create<CoreProjectionManagementMessage.Faulted>(_managerInputQueue));
                    projectionNode.CoreOutput.Subscribe(
                        Forwarder.Create<CoreProjectionManagementMessage.Prepared>(_managerInputQueue));

                }
                projectionNode.CoreOutput.Subscribe(timerService);


                projectionNode.CoreOutput.Subscribe(Forwarder.Create<Message>(coreQueue)); // forward all

                coreInputBus.Subscribe(new UnwrapEnvelopeHandler());

                _coreQueues.Add(coreQueue);
            }

            _managerInputBus.Subscribe(
            Forwarder.CreateBalancing<FeedReaderMessage.ReadPage>(_coreQueues.Cast<IPublisher>().ToArray()));

            _projectionManagerNode = ProjectionManagerNode.Create(
                db, _managerInputQueue, httpForwarder, httpServices, networkSendQueue,
                _coreQueues.Cast<IPublisher>().ToArray(), runProjections);
            _projectionManagerNode.SetupMessaging(_managerInputBus);
            {
                var forwarder = new RequestResponseQueueForwarder(
                    inputQueue: _managerInputQueue, externalRequestQueue: mainQueue);
                _projectionManagerNode.Output.Subscribe<ClientMessage.ReadEvent>(forwarder);
                _projectionManagerNode.Output.Subscribe<ClientMessage.ReadStreamEventsBackward>(forwarder);
                _projectionManagerNode.Output.Subscribe<ClientMessage.ReadStreamEventsForward>(forwarder);
                _projectionManagerNode.Output.Subscribe<ClientMessage.WriteEvents>(forwarder);
                _projectionManagerNode.Output.Subscribe(
                    Forwarder.Create<ProjectionManagementMessage.RequestSystemProjections>(mainQueue));
                _projectionManagerNode.Output.Subscribe(Forwarder.Create<Message>(_managerInputQueue));

                _projectionManagerNode.Output.Subscribe(timerService);

                // self forward all

                mainBus.Subscribe(Forwarder.Create<SystemMessage.StateChangeMessage>(_managerInputQueue));
                _managerInputBus.Subscribe(new UnwrapEnvelopeHandler());
            }
        }
        private void SetUpCoreServices(
            Guid workerId,
            IBus bus,
            IPublisher inputQueue,
            InMemoryBus output_,
            ISingletonTimeoutScheduler timeoutScheduler)
        {
            var         output           = (output_ ?? inputQueue);
            ICheckpoint writerCheckpoint = new InMemoryCheckpoint(1000);
            var         readerService    = new EventReaderCoreService(
                output,
                _ioDispatcher,
                10,
                writerCheckpoint,
                runHeadingReader: true, faultOutOfOrderProjections: true);

            _subscriptionDispatcher = new ReaderSubscriptionDispatcher(inputQueue);

            bus.Subscribe(
                _subscriptionDispatcher.CreateSubscriber <EventReaderSubscriptionMessage.CheckpointSuggested>());
            bus.Subscribe(
                _subscriptionDispatcher.CreateSubscriber <EventReaderSubscriptionMessage.CommittedEventReceived>());
            bus.Subscribe(_subscriptionDispatcher.CreateSubscriber <EventReaderSubscriptionMessage.EofReached>());
            bus.Subscribe(
                _subscriptionDispatcher.CreateSubscriber <EventReaderSubscriptionMessage.PartitionEofReached>());
            bus.Subscribe(_subscriptionDispatcher.CreateSubscriber <EventReaderSubscriptionMessage.PartitionDeleted>());
            bus.Subscribe(_subscriptionDispatcher.CreateSubscriber <EventReaderSubscriptionMessage.ProgressChanged>());
            bus.Subscribe(
                _subscriptionDispatcher.CreateSubscriber <EventReaderSubscriptionMessage.SubscriptionStarted>());
            bus.Subscribe(_subscriptionDispatcher.CreateSubscriber <EventReaderSubscriptionMessage.NotAuthorized>());
            bus.Subscribe(
                _subscriptionDispatcher.CreateSubscriber <EventReaderSubscriptionMessage.ReaderAssignedReader>());

            var ioDispatcher = new IODispatcher(output, new PublishEnvelope(inputQueue), true);
//            var coreServiceCommandReader = new ProjectionCoreServiceCommandReader(
//                output,
//                ioDispatcher,
//                workerId.ToString("N"));

            var coreService = new ProjectionCoreService(
                workerId,
                inputQueue,
                output,
                _subscriptionDispatcher,
                _timeProvider,
                ioDispatcher,
                timeoutScheduler);

            bus.Subscribe <CoreProjectionManagementMessage.CreateAndPrepare>(coreService);
            bus.Subscribe <CoreProjectionManagementMessage.CreatePrepared>(coreService);
            bus.Subscribe <CoreProjectionManagementMessage.Dispose>(coreService);
            bus.Subscribe <CoreProjectionManagementMessage.Start>(coreService);
            bus.Subscribe <CoreProjectionManagementMessage.LoadStopped>(coreService);
            bus.Subscribe <CoreProjectionManagementMessage.Stop>(coreService);
            bus.Subscribe <CoreProjectionManagementMessage.Kill>(coreService);
            bus.Subscribe <CoreProjectionManagementMessage.GetState>(coreService);
            bus.Subscribe <CoreProjectionManagementMessage.GetResult>(coreService);
            bus.Subscribe <CoreProjectionProcessingMessage.CheckpointCompleted>(coreService);
            bus.Subscribe <CoreProjectionProcessingMessage.CheckpointLoaded>(coreService);
            bus.Subscribe <CoreProjectionProcessingMessage.PrerecordedEventsLoaded>(coreService);
            bus.Subscribe <CoreProjectionProcessingMessage.RestartRequested>(coreService);
            bus.Subscribe <CoreProjectionProcessingMessage.Failed>(coreService);
            bus.Subscribe <ClientMessage.ReadStreamEventsForwardCompleted>(ioDispatcher.ForwardReader);
            bus.Subscribe <ClientMessage.ReadStreamEventsBackwardCompleted>(ioDispatcher.BackwardReader);
            bus.Subscribe <ClientMessage.WriteEventsCompleted>(ioDispatcher.Writer);
            bus.Subscribe <ClientMessage.DeleteStreamCompleted>(ioDispatcher.StreamDeleter);
            bus.Subscribe <IODispatcherDelayedMessage>(ioDispatcher.Awaker);
            bus.Subscribe <IODispatcherDelayedMessage>(ioDispatcher);
            bus.Subscribe <ProjectionCoreServiceMessage.StartCore>(coreService);
            bus.Subscribe <ProjectionCoreServiceMessage.StopCore>(coreService);
            bus.Subscribe <ReaderCoreServiceMessage.StartReader>(readerService);
            bus.Subscribe <ReaderCoreServiceMessage.StopReader>(readerService);
            bus.Subscribe <ProjectionCoreServiceMessage.CoreTick>(coreService);
            bus.Subscribe <ReaderSubscriptionMessage.CommittedEventDistributed>(readerService);
            bus.Subscribe <ReaderSubscriptionMessage.EventReaderEof>(readerService);
            bus.Subscribe <ReaderSubscriptionMessage.EventReaderPartitionEof>(readerService);
            bus.Subscribe <ReaderSubscriptionMessage.EventReaderPartitionDeleted>(readerService);
            bus.Subscribe <ReaderSubscriptionMessage.EventReaderNotAuthorized>(readerService);
            bus.Subscribe <ReaderSubscriptionMessage.EventReaderIdle>(readerService);
            bus.Subscribe <ReaderSubscriptionMessage.EventReaderStarting>(readerService);
            bus.Subscribe <ReaderSubscriptionManagement.Pause>(readerService);
            bus.Subscribe <ReaderSubscriptionManagement.Resume>(readerService);
            bus.Subscribe <ReaderSubscriptionManagement.Subscribe>(readerService);
            bus.Subscribe <ReaderSubscriptionManagement.Unsubscribe>(readerService);

            if (output_ != null)
            {
                bus.Subscribe(new UnwrapEnvelopeHandler());
                output_.Subscribe(Forwarder.Create <CoreProjectionStatusMessage.StateReport>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create <CoreProjectionStatusMessage.ResultReport>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create <CoreProjectionStatusMessage.StatisticsReport>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create <CoreProjectionStatusMessage.Started>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create <CoreProjectionStatusMessage.Stopped>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create <CoreProjectionStatusMessage.Faulted>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create <CoreProjectionStatusMessage.Prepared>(GetInputQueue()));
                output_.Subscribe(
                    Forwarder.Create <ProjectionManagementMessage.Command.ControlMessage>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create <AwakeServiceMessage.SubscribeAwake>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create <AwakeServiceMessage.UnsubscribeAwake>(GetInputQueue()));
                output_.Subscribe(Forwarder.Create <Message>(inputQueue));                // forward all

                var forwarder = new RequestResponseQueueForwarder(
                    inputQueue: inputQueue,
                    externalRequestQueue: GetInputQueue());
                // forwarded messages
                output_.Subscribe <ClientMessage.ReadEvent>(forwarder);
                output_.Subscribe <ClientMessage.ReadStreamEventsBackward>(forwarder);
                output_.Subscribe <ClientMessage.ReadStreamEventsForward>(forwarder);
                output_.Subscribe <ClientMessage.ReadAllEventsForward>(forwarder);
                output_.Subscribe <ClientMessage.WriteEvents>(forwarder);
            }
        }
        public static Dictionary <Guid, IQueuedHandler> CreateCoreWorkers(
            StandardComponents standardComponents,
            ProjectionsStandardComponents projectionsStandardComponents)
        {
            var coreTimeoutSchedulers =
                CreateTimeoutSchedulers(projectionsStandardComponents.ProjectionWorkerThreadCount);

            var coreQueues = new Dictionary <Guid, IQueuedHandler>();

            while (coreQueues.Count < projectionsStandardComponents.ProjectionWorkerThreadCount)
            {
                var coreInputBus = new InMemoryBus("bus");
                var coreQueue    = QueuedHandler.CreateQueuedHandler(coreInputBus,
                                                                     "Projection Core #" + coreQueues.Count,
                                                                     groupName: "Projection Core");
                var workerId       = Guid.NewGuid();
                var projectionNode = new ProjectionWorkerNode(
                    workerId,
                    standardComponents.Db,
                    coreQueue,
                    standardComponents.TimeProvider,
                    coreTimeoutSchedulers[coreQueues.Count],
                    projectionsStandardComponents.RunProjections);
                projectionNode.SetupMessaging(coreInputBus);

                var forwarder = new RequestResponseQueueForwarder(
                    inputQueue: coreQueue,
                    externalRequestQueue: standardComponents.MainQueue);
                // forwarded messages
                var coreOutput = projectionNode.CoreOutput;
                coreOutput.Subscribe <ClientMessage.ReadEvent>(forwarder);
                coreOutput.Subscribe <ClientMessage.ReadStreamEventsBackward>(forwarder);
                coreOutput.Subscribe <ClientMessage.ReadStreamEventsForward>(forwarder);
                coreOutput.Subscribe <ClientMessage.ReadAllEventsForward>(forwarder);
                coreOutput.Subscribe <ClientMessage.WriteEvents>(forwarder);
                coreOutput.Subscribe <ClientMessage.DeleteStream>(forwarder);


                if (projectionsStandardComponents.RunProjections >= ProjectionType.System)
                {
                    var slaveProjectionResponseWriter = projectionNode.SlaveProjectionResponseWriter;
                    coreOutput.Subscribe <PartitionMeasuredOutput>(slaveProjectionResponseWriter);
                    coreOutput.Subscribe <PartitionProcessingProgressOutput>(slaveProjectionResponseWriter);
                    coreOutput.Subscribe <PartitionProcessingResultOutput>(slaveProjectionResponseWriter);
                    coreOutput.Subscribe <ReaderSubscriptionManagement.SpoolStreamReading>(slaveProjectionResponseWriter);


                    coreOutput.Subscribe(
                        Forwarder.Create <AwakeServiceMessage.SubscribeAwake>(standardComponents.MainQueue));
                    coreOutput.Subscribe(
                        Forwarder.Create <AwakeServiceMessage.UnsubscribeAwake>(standardComponents.MainQueue));
                }
                coreOutput.Subscribe <TimerMessage.Schedule>(standardComponents.TimerService);


                coreOutput.Subscribe(Forwarder.Create <Message>(coreQueue)); // forward all

                coreInputBus.Subscribe(new UnwrapEnvelopeHandler());

                coreQueues.Add(workerId, coreQueue);
            }
            var queues      = coreQueues.Select(v => v.Value).Cast <IPublisher>().ToArray();
            var coordinator = new ProjectionCoreCoordinator(
                projectionsStandardComponents.RunProjections,
                coreTimeoutSchedulers,
                queues,
                projectionsStandardComponents.MasterOutputBus,
                new PublishEnvelope(projectionsStandardComponents.MasterInputQueue, crossThread: true));

            coordinator.SetupMessaging(projectionsStandardComponents.MasterMainBus);
            projectionsStandardComponents.MasterMainBus.Subscribe(
                Forwarder.CreateBalancing <FeedReaderMessage.ReadPage>(coreQueues.Values.Cast <IPublisher>().ToArray()));
            return(coreQueues);
        }
Beispiel #11
0
        private void SetupMessaging(
            TFChunkDb db, QueuedHandler mainQueue, InMemoryBus mainBus, TimerService timerService,
            HttpService httpService)
        {
            _coreQueues        = new List <QueuedHandler>();
            _managerInputBus   = new InMemoryBus("manager input bus");
            _managerInputQueue = new QueuedHandler(_managerInputBus, "ProjectionManager");

            while (_coreQueues.Count < _projectionWorkerThreadCount)
            {
                var coreInputBus   = new InMemoryBus("bus");
                var coreQueue      = new QueuedHandler(coreInputBus, "ProjectionCoreQueue #" + _coreQueues.Count);
                var projectionNode = new ProjectionWorkerNode(db, coreQueue);
                projectionNode.SetupMessaging(coreInputBus);


                var forwarder = new RequestResponseQueueForwarder(
                    inputQueue: coreQueue, externalRequestQueue: mainQueue);
                // forwarded messages
                projectionNode.CoreOutput.Subscribe <ClientMessage.ReadEvent>(forwarder);
                projectionNode.CoreOutput.Subscribe <ClientMessage.ReadStreamEventsBackward>(forwarder);
                projectionNode.CoreOutput.Subscribe <ClientMessage.ReadStreamEventsForward>(forwarder);
                projectionNode.CoreOutput.Subscribe <ClientMessage.ReadAllEventsForward>(forwarder);
                projectionNode.CoreOutput.Subscribe <ClientMessage.WriteEvents>(forwarder);

                projectionNode.CoreOutput.Subscribe(
                    Forwarder.Create <CoreProjectionManagementMessage.StateReport>(_managerInputQueue));
                projectionNode.CoreOutput.Subscribe(
                    Forwarder.Create <CoreProjectionManagementMessage.StatisticsReport>(_managerInputQueue));
                projectionNode.CoreOutput.Subscribe(
                    Forwarder.Create <CoreProjectionManagementMessage.Started>(_managerInputQueue));
                projectionNode.CoreOutput.Subscribe(
                    Forwarder.Create <CoreProjectionManagementMessage.Stopped>(_managerInputQueue));
                projectionNode.CoreOutput.Subscribe(
                    Forwarder.Create <CoreProjectionManagementMessage.Faulted>(_managerInputQueue));
                projectionNode.CoreOutput.Subscribe(
                    Forwarder.Create <CoreProjectionManagementMessage.Prepared>(_managerInputQueue));

                projectionNode.CoreOutput.Subscribe(timerService);


                projectionNode.CoreOutput.Subscribe(Forwarder.Create <Message>(coreQueue)); // forward all

                coreInputBus.Subscribe(new UnwrapEnvelopeHandler());

                _coreQueues.Add(coreQueue);
            }


            _projectionManagerNode = ProjectionManagerNode.Create(
                db, _managerInputQueue, httpService, _coreQueues.Cast <IPublisher>().ToArray());
            _projectionManagerNode.SetupMessaging(_managerInputBus);
            {
                var forwarder = new RequestResponseQueueForwarder(
                    inputQueue: _managerInputQueue, externalRequestQueue: mainQueue);
                _projectionManagerNode.Output.Subscribe <ClientMessage.ReadEvent>(forwarder);
                _projectionManagerNode.Output.Subscribe <ClientMessage.ReadStreamEventsBackward>(forwarder);
                _projectionManagerNode.Output.Subscribe <ClientMessage.ReadStreamEventsForward>(forwarder);
                _projectionManagerNode.Output.Subscribe <ClientMessage.WriteEvents>(forwarder);
                _projectionManagerNode.Output.Subscribe(Forwarder.Create <Message>(_managerInputQueue));
                // self forward all

                mainBus.Subscribe(Forwarder.Create <SystemMessage.StateChangeMessage>(_managerInputQueue));
                _managerInputBus.Subscribe(new UnwrapEnvelopeHandler());
            }
        }
        private static void SubscribeOutputBus(
            StandardComponents standardComponents,
            ProjectionsStandardComponents projectionsStandardComponents,
            RequestResponseQueueForwarder forwarder)
        {
            var managerOutput = projectionsStandardComponents.MasterOutputBus;
            managerOutput.Subscribe<ClientMessage.ReadEvent>(forwarder);
            managerOutput.Subscribe<ClientMessage.ReadStreamEventsBackward>(forwarder);
            managerOutput.Subscribe<ClientMessage.ReadStreamEventsForward>(forwarder);
            managerOutput.Subscribe<ClientMessage.WriteEvents>(forwarder);
            managerOutput.Subscribe<ClientMessage.DeleteStream>(forwarder);
            managerOutput.Subscribe(
                Forwarder.Create<ProjectionManagementMessage.RequestSystemProjections>(standardComponents.MainQueue));
            managerOutput.Subscribe(Forwarder.Create<Message>(projectionsStandardComponents.MasterInputQueue));

            managerOutput.Subscribe<TimerMessage.Schedule>(standardComponents.TimerService);
            managerOutput.Subscribe(Forwarder.Create<AwakeServiceMessage.SubscribeAwake>(standardComponents.MainQueue));
            managerOutput.Subscribe(
                Forwarder.Create<AwakeServiceMessage.UnsubscribeAwake>(standardComponents.MainQueue));
            managerOutput.Subscribe<SystemMessage.SubSystemInitialized>(forwarder);

            // self forward all
            standardComponents.MainBus.Subscribe(
                Forwarder.Create<SystemMessage.StateChangeMessage>(projectionsStandardComponents.MasterInputQueue));
            standardComponents.MainBus.Subscribe(
                Forwarder.Create<SystemMessage.SystemCoreReady>(projectionsStandardComponents.MasterInputQueue));
            projectionsStandardComponents.MasterMainBus.Subscribe(new UnwrapEnvelopeHandler());
        }
Beispiel #13
0
        private void SetupMessaging(
            TFChunkDb db, QueuedHandler mainQueue, ISubscriber mainBus, TimerService timerService, ITimeProvider timeProvider,
            IHttpForwarder httpForwarder, HttpService[] httpServices, IPublisher networkSendQueue, RunProjections runProjections)
        {
            _coreQueues        = new List <QueuedHandler>();
            _managerInputBus   = new InMemoryBus("manager input bus");
            _managerInputQueue = new QueuedHandler(_managerInputBus, "Projections Master");
            while (_coreQueues.Count < _projectionWorkerThreadCount)
            {
                var coreInputBus = new InMemoryBus("bus");
                var coreQueue    = new QueuedHandler(
                    coreInputBus, "Projection Core #" + _coreQueues.Count, groupName: "Projection Core");
                var projectionNode = new ProjectionWorkerNode(db, coreQueue, timeProvider, runProjections);
                projectionNode.SetupMessaging(coreInputBus);


                var forwarder = new RequestResponseQueueForwarder(
                    inputQueue: coreQueue, externalRequestQueue: mainQueue);
                // forwarded messages
                projectionNode.CoreOutput.Subscribe <ClientMessage.ReadEvent>(forwarder);
                projectionNode.CoreOutput.Subscribe <ClientMessage.ReadStreamEventsBackward>(forwarder);
                projectionNode.CoreOutput.Subscribe <ClientMessage.ReadStreamEventsForward>(forwarder);
                projectionNode.CoreOutput.Subscribe <ClientMessage.ReadAllEventsForward>(forwarder);
                projectionNode.CoreOutput.Subscribe <ClientMessage.WriteEvents>(forwarder);


                if (runProjections >= RunProjections.System)
                {
                    projectionNode.CoreOutput.Subscribe(
                        Forwarder.Create <CoreProjectionManagementMessage.StateReport>(_managerInputQueue));
                    projectionNode.CoreOutput.Subscribe(
                        Forwarder.Create <CoreProjectionManagementMessage.ResultReport>(_managerInputQueue));
                    projectionNode.CoreOutput.Subscribe(
                        Forwarder.Create <CoreProjectionManagementMessage.StatisticsReport>(_managerInputQueue));
                    projectionNode.CoreOutput.Subscribe(
                        Forwarder.Create <CoreProjectionManagementMessage.Started>(_managerInputQueue));
                    projectionNode.CoreOutput.Subscribe(
                        Forwarder.Create <CoreProjectionManagementMessage.Stopped>(_managerInputQueue));
                    projectionNode.CoreOutput.Subscribe(
                        Forwarder.Create <CoreProjectionManagementMessage.Faulted>(_managerInputQueue));
                    projectionNode.CoreOutput.Subscribe(
                        Forwarder.Create <CoreProjectionManagementMessage.Prepared>(_managerInputQueue));
                    projectionNode.CoreOutput.Subscribe(
                        Forwarder.Create <CoreProjectionManagementMessage.SlaveProjectionReaderAssigned>(
                            _managerInputQueue));
                    projectionNode.CoreOutput.Subscribe(
                        Forwarder.Create <ProjectionManagementMessage.ControlMessage>(_managerInputQueue));
                }
                projectionNode.CoreOutput.Subscribe <TimerMessage.Schedule>(timerService);


                projectionNode.CoreOutput.Subscribe(Forwarder.Create <Message>(coreQueue)); // forward all

                coreInputBus.Subscribe(new UnwrapEnvelopeHandler());

                _coreQueues.Add(coreQueue);
            }

            _managerInputBus.Subscribe(
                Forwarder.CreateBalancing <FeedReaderMessage.ReadPage>(_coreQueues.Cast <IPublisher>().ToArray()));

            _projectionManagerNode = ProjectionManagerNode.Create(
                db, _managerInputQueue, httpForwarder, httpServices, networkSendQueue,
                _coreQueues.Cast <IPublisher>().ToArray(), runProjections);
            _projectionManagerNode.SetupMessaging(_managerInputBus);
            {
                var forwarder = new RequestResponseQueueForwarder(
                    inputQueue: _managerInputQueue, externalRequestQueue: mainQueue);
                _projectionManagerNode.Output.Subscribe <ClientMessage.ReadEvent>(forwarder);
                _projectionManagerNode.Output.Subscribe <ClientMessage.ReadStreamEventsBackward>(forwarder);
                _projectionManagerNode.Output.Subscribe <ClientMessage.ReadStreamEventsForward>(forwarder);
                _projectionManagerNode.Output.Subscribe <ClientMessage.WriteEvents>(forwarder);
                _projectionManagerNode.Output.Subscribe(
                    Forwarder.Create <ProjectionManagementMessage.RequestSystemProjections>(mainQueue));
                _projectionManagerNode.Output.Subscribe(Forwarder.Create <Message>(_managerInputQueue));

                _projectionManagerNode.Output.Subscribe <TimerMessage.Schedule>(timerService);

                // self forward all

                mainBus.Subscribe(Forwarder.Create <SystemMessage.StateChangeMessage>(_managerInputQueue));
                _managerInputBus.Subscribe(new UnwrapEnvelopeHandler());
            }
        }
Beispiel #14
0
        private void SetupMessaging(
            TFChunkDb db, QueuedHandler mainQueue, InMemoryBus mainBus, TimerService timerService,
            HttpService httpService)
        {
            _coreQueues = new List<QueuedHandler>();
            _managerInputBus = new InMemoryBus("manager input bus");
            _managerInputQueue = new QueuedHandler(_managerInputBus, "ProjectionManager");

            while (_coreQueues.Count < _projectionWorkerThreadCount)
            {
                var coreInputBus = new InMemoryBus("bus");
                var coreQueue = new QueuedHandler(coreInputBus, "ProjectionCoreQueue #" + _coreQueues.Count);
                var projectionNode = new ProjectionWorkerNode(db, coreQueue);
                projectionNode.SetupMessaging(coreInputBus);

                var forwarder = new RequestResponseQueueForwarder(
                    inputQueue: coreQueue, externalRequestQueue: mainQueue);
                // forwarded messages
                projectionNode.CoreOutput.Subscribe<ClientMessage.ReadEvent>(forwarder);
                projectionNode.CoreOutput.Subscribe<ClientMessage.ReadStreamEventsBackward>(forwarder);
                projectionNode.CoreOutput.Subscribe<ClientMessage.ReadStreamEventsForward>(forwarder);
                projectionNode.CoreOutput.Subscribe<ClientMessage.ReadAllEventsForward>(forwarder);
                projectionNode.CoreOutput.Subscribe<ClientMessage.WriteEvents>(forwarder);

                projectionNode.CoreOutput.Subscribe(
                    Forwarder.Create<ProjectionMessage.Projections.Management.StateReport>(_managerInputQueue));
                projectionNode.CoreOutput.Subscribe(
                    Forwarder.Create<ProjectionMessage.Projections.Management.StatisticsReport>(_managerInputQueue));
                projectionNode.CoreOutput.Subscribe(
                    Forwarder.Create<ProjectionMessage.Projections.StatusReport.Started>(_managerInputQueue));
                projectionNode.CoreOutput.Subscribe(
                    Forwarder.Create<ProjectionMessage.Projections.StatusReport.Stopped>(_managerInputQueue));
                projectionNode.CoreOutput.Subscribe(
                    Forwarder.Create<ProjectionMessage.Projections.StatusReport.Faulted>(_managerInputQueue));

                projectionNode.CoreOutput.Subscribe(timerService);

                projectionNode.CoreOutput.Subscribe(Forwarder.Create<Message>(coreQueue)); // forward all

                coreInputBus.Subscribe(new UnwrapEnvelopeHandler());

                _coreQueues.Add(coreQueue);
            }

            _projectionManagerNode = ProjectionManagerNode.Create(
                db, _managerInputQueue, httpService, _coreQueues.Cast<IPublisher>().ToArray());
            _projectionManagerNode.SetupMessaging(_managerInputBus);
            {
                var forwarder = new RequestResponseQueueForwarder(
                    inputQueue: _managerInputQueue, externalRequestQueue: mainQueue);
                _projectionManagerNode.Output.Subscribe<ClientMessage.ReadEvent>(forwarder);
                _projectionManagerNode.Output.Subscribe<ClientMessage.ReadStreamEventsBackward>(forwarder);
                _projectionManagerNode.Output.Subscribe<ClientMessage.ReadStreamEventsForward>(forwarder);
                _projectionManagerNode.Output.Subscribe<ClientMessage.WriteEvents>(forwarder);
                _projectionManagerNode.Output.Subscribe(Forwarder.Create<Message>(_managerInputQueue));
                    // self forward all

                mainBus.Subscribe(Forwarder.Create<SystemMessage.SystemInit>(_managerInputQueue));
                mainBus.Subscribe(Forwarder.Create<SystemMessage.SystemStart>(_managerInputQueue));
                mainBus.Subscribe(Forwarder.Create<SystemMessage.StateChangeMessage>(_managerInputQueue));
                _managerInputBus.Subscribe(new UnwrapEnvelopeHandler());
            }
        }