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);
        }
Esempio n. 2
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());
            }
        }