public IEnumerable <IWorkerInfo <TMessage> > GetAvailableWorkers <TMessage>(IConsumeContext <TMessage> context,
                                                                                    IWorkerSelector <TMessage> selector)
            where TMessage : class
        {
            IEnumerable <IWorkerInfo <TMessage> > candidates =
                _typeWorkers[typeof(TMessage)].Select(x => x.GetWorker <TMessage>());

            return(selector.SelectWorker(candidates, context));
        }
        public UnsubscribeAction Connect(IInboundPipelineConfigurator configurator, IDistributor distributor)
        {
            IWorkerAvailability <TMessage> workerAvailability = distributor.GetWorkerAvailability <TMessage>();

            // TODO we need to make a saga worker availability so that we can split saga load by correlation id
            IWorkerSelector <TMessage> workerSelector = _workerSelectorFactory.GetSelector <TMessage>();

            var sink = new DistributorMessageSink <TMessage>(workerAvailability, workerSelector);

            return(configurator.Pipeline.ConnectToRouter(sink, () => configurator.SubscribedTo <TMessage>()));
        }
        IEnumerable <Action <IConsumeContext <TMessage> > > IWorkerAvailability <TMessage> .GetWorker(
            IConsumeContext <TMessage> context,
            Func <IWorkerInfo <TMessage>, IEnumerable <Action <IConsumeContext <TMessage> > > > selector,
            IWorkerSelector <TMessage> workerSelector)
        {
            return(_workerCache.GetAvailableWorkers(context, workerSelector)
                   .Take(1)
                   .SelectMany(worker =>
            {
                worker.Assigned();

                return selector(worker);
            }));
        }
 public DistributorMessageSink(IWorkerAvailability <TMessage> workerAvailability,
                               IWorkerSelector <TMessage> workerSelector)
 {
     _workerAvailability = workerAvailability;
     _workerSelector     = workerSelector;
 }