예제 #1
0
        public ConnectHandle ConnectConsumer(IConsumePipeConnector consumePipe, IConsumerFactory <TConsumer> consumerFactory,
                                             IConsumerSpecification <TConsumer> specification)
        {
            var jobServiceOptions = specification.Options <JobServiceOptions>();

            if (jobServiceOptions.JobService == null)
            {
                throw new ConfigurationException(
                          "The job service must be configured prior to configuring a job consumer, using either ConfigureJobServiceEndpoints or ConfigureJobService");
            }

            var options = specification.Options <JobOptions <TJob> >();

            IConsumerMessageSpecification <TConsumer, TJob> messageSpecification = specification.GetMessageSpecification <TJob>();

            var turnoutSpecification = messageSpecification as JobConsumerMessageSpecification <TConsumer, TJob>;

            if (turnoutSpecification == null)
            {
                throw new ArgumentException("The consumer specification did not match the message specification type");
            }

            var submitJobHandle = ConnectSubmitJobConsumer(consumePipe, turnoutSpecification.SubmitJobSpecification, options);

            var startJobHandle = ConnectStartJobConsumer(consumePipe, turnoutSpecification.StartJobSpecification, options, jobServiceOptions.JobService,
                                                         CreateJobPipe(consumerFactory, specification));

            var cancelJobHandle = ConnectSuperviseJobConsumer(consumePipe, turnoutSpecification.SuperviseJobSpecification, jobServiceOptions.JobService);

            return(new MultipleConnectHandle(submitJobHandle, startJobHandle, cancelJobHandle));
        }
예제 #2
0
        ConnectHandle ConnectStartJobConsumer(IConsumePipeConnector consumePipe, IConsumerSpecification <StartJobConsumer <TJob> > specification,
                                              JobOptions <TJob> options, IJobService jobService, IPipe <ConsumeContext <TJob> > pipe)
        {
            var consumerFactory = new DelegateConsumerFactory <StartJobConsumer <TJob> >(() => new StartJobConsumer <TJob>(jobService, options, pipe));

            return(_startJobConsumerConnector.ConnectConsumer(consumePipe, consumerFactory, specification));
        }
예제 #3
0
        public ConnectHandle ConnectConsumer(IConsumePipeConnector consumePipe, IConsumerFactory <TConsumer> consumerFactory,
                                             IConsumerSpecification <TConsumer> specification)
        {
            var options = specification.Options <BatchOptions>();

            var messageLimit     = options.MessageLimit;
            var timeLimit        = options.TimeLimit;
            var concurrencyLimit = options.ConcurrencyLimit;

            IConsumerMessageSpecification <TConsumer, Batch <TMessage> > batchMessageSpecification = specification.GetMessageSpecification <Batch <TMessage> >();

            var consumeFilter = new MethodConsumerMessageFilter <TConsumer, Batch <TMessage> >();

            IPipe <ConsumerConsumeContext <TConsumer, Batch <TMessage> > > batchConsumerPipe = batchMessageSpecification.Build(consumeFilter);

            IPipe <ConsumeContext <Batch <TMessage> > > batchMessagePipe = batchMessageSpecification.BuildMessagePipe(x =>
            {
                x.UseFilter(new ConsumerMessageFilter <TConsumer, Batch <TMessage> >(consumerFactory, batchConsumerPipe));
            });

            IBatchCollector <TMessage> collector = null;

            if (options.GroupKeyProvider == null)
            {
                collector = new BatchCollector <TMessage>(messageLimit, timeLimit, concurrencyLimit, batchMessagePipe);
            }
            else
            {
                if (options.GroupKeyProvider.GetType().ClosesType(typeof(IGroupKeyProvider <,>), out Type[] types))
예제 #4
0
        ConnectHandle ConnectSuperviseJobConsumer(IConsumePipeConnector consumePipe, IConsumerSpecification <SuperviseJobConsumer> specification,
                                                  IJobService jobService)
        {
            var consumerFactory = new DelegateConsumerFactory <SuperviseJobConsumer>(() => new SuperviseJobConsumer(jobService));

            return(_superviseJobConsumerConnector.ConnectConsumer(consumePipe, consumerFactory, specification));
        }
예제 #5
0
        ConnectHandle IInstanceMessageConnector <TConsumer> .ConnectInstance(IConsumePipeConnector pipeConnector, TConsumer instance,
                                                                             IConsumerSpecification <TConsumer> specification)
        {
            if (pipeConnector == null)
            {
                throw new ArgumentNullException(nameof(pipeConnector));
            }
            if (instance == null)
            {
                throw new ArgumentNullException(nameof(instance));
            }
            if (specification == null)
            {
                throw new ArgumentNullException(nameof(specification));
            }

            IConsumerMessageSpecification <TConsumer, TMessage> messageSpecification = specification.GetMessageSpecification <TMessage>();

            IPipe <ConsumerConsumeContext <TConsumer, TMessage> > consumerPipe = messageSpecification.Build(_consumeFilter);

            IPipe <ConsumeContext <TMessage> > messagePipe = Pipe.New <ConsumeContext <TMessage> >(x =>
            {
                x.UseFilter(new InstanceMessageFilter <TConsumer, TMessage>(instance, consumerPipe));
            });

            return(pipeConnector.ConnectConsumePipe(messagePipe));
        }
        public ConnectHandle ConnectConsumer(IConsumePipeConnector consumePipe, IConsumerFactory <TConsumer> consumerFactory,
                                             IConsumerSpecification <TConsumer> specification)
        {
            var options = specification.Options <BatchOptions>();

            var messageLimit     = options.MessageLimit;
            var timeLimit        = options.TimeLimit;
            var concurrencyLimit = options.ConcurrencyLimit;

            IConsumerMessageSpecification <TConsumer, Batch <TMessage> > batchMessageSpecification = specification.GetMessageSpecification <Batch <TMessage> >();

            var consumeFilter = new MethodConsumerMessageFilter <TConsumer, Batch <TMessage> >();

            IPipe <ConsumerConsumeContext <TConsumer, Batch <TMessage> > > batchConsumerPipe = batchMessageSpecification.Build(consumeFilter);

            var factory = new BatchConsumerFactory <TConsumer, TMessage>(consumerFactory, messageLimit, concurrencyLimit, timeLimit, batchConsumerPipe);

            IConsumerSpecification <IConsumer <TMessage> > messageConsumerSpecification =
                ConsumerConnectorCache <IConsumer <TMessage> > .Connector.CreateConsumerSpecification <IConsumer <TMessage> >();

            IConsumerMessageSpecification <IConsumer <TMessage>, TMessage> messageSpecification =
                messageConsumerSpecification.GetMessageSpecification <TMessage>();

            IPipe <ConsumerConsumeContext <IConsumer <TMessage>, TMessage> > consumerPipe =
                messageSpecification.Build(new MethodConsumerMessageFilter <IConsumer <TMessage>, TMessage>());

            IPipe <ConsumeContext <TMessage> > messagePipe = messageSpecification.BuildMessagePipe(x =>
            {
                x.UseFilter(new ConsumerMessageFilter <IConsumer <TMessage>, TMessage>(factory, consumerPipe));
            });

            var handle = consumePipe.ConnectConsumePipe(messagePipe);

            return(new BatchConnectHandle(handle, factory));
        }
예제 #7
0
        ConnectHandle ConnectCancelJobConsumer(IConsumePipeConnector consumePipe, IConsumerSpecification <CancelJobConsumer <TJob> > specification,
                                               IJobService jobService)
        {
            var consumerFactory = new DelegateConsumerFactory <CancelJobConsumer <TJob> >(() => new CancelJobConsumer <TJob>(jobService));

            return(_cancelJobConsumerConnector.ConnectConsumer(consumePipe, consumerFactory, specification));
        }
예제 #8
0
        ConnectHandle ConnectSubmitJobConsumer(IConsumePipeConnector consumePipe,
                                               IConsumerSpecification <SubmitJobConsumer <TJob> > specification, JobOptions <TJob> options)
        {
            var consumerFactory = new DelegateConsumerFactory <SubmitJobConsumer <TJob> >(() => new SubmitJobConsumer <TJob>(options));

            return(_submitJobConsumerConnector.ConnectConsumer(consumePipe, consumerFactory, specification));
        }
예제 #9
0
        ConnectHandle IConsumerConnector.ConnectConsumer <TConsumer>(IConsumePipeConnector consumePipe, IConsumerFactory <TConsumer> consumerFactory,
                                                                     IConsumerSpecification <TConsumer> specification)
        {
            var handles = new List <ConnectHandle>();

            try
            {
                foreach (IConsumerMessageConnector <TConsumer> connector in _connectors.Cast <IConsumerMessageConnector <TConsumer> >())
                {
                    var handle = connector.ConnectConsumer(consumePipe, consumerFactory, specification);

                    handles.Add(handle);
                }

                return(new MultipleConnectHandle(handles));
            }
            catch (Exception)
            {
                foreach (var handle in handles)
                {
                    handle.Dispose();
                }
                throw;
            }
        }
        public UntypedConsumerConfigurator(Func <Type, object> consumerFactory, IConsumerConfigurationObserver observer)
        {
            _consumerFactory = new DelegateConsumerFactory <TConsumer>(() => (TConsumer)consumerFactory(typeof(TConsumer)));

            _specification = ConsumerConnectorCache <TConsumer> .Connector.CreateConsumerSpecification <TConsumer>();

            _specification.ConnectConsumerConfigurationObserver(observer);
        }
        public ConsumerConfigurator(IConsumerFactory <TConsumer> consumerFactory, IConsumerConfigurationObserver observer)
        {
            _consumerFactory = consumerFactory;

            _specification = ConsumerConnectorCache <TConsumer> .Connector.CreateConsumerSpecification <TConsumer>();

            _specification.ConnectConsumerConfigurationObserver(observer);
        }
예제 #12
0
        ConnectHandle ConnectFinalizeJobConsumer(IConsumePipeConnector consumePipe, IConsumerSpecification <FinalizeJobConsumer <TJob> > specification,
                                                 JobOptions <TJob> options, Guid jobTypeId, IJobService jobService)
        {
            var consumerFactory = new DelegateConsumerFactory <FinalizeJobConsumer <TJob> >(() => new FinalizeJobConsumer <TJob>(jobService, options, jobTypeId,
                                                                                                                                 TypeMetadataCache <TConsumer> .ShortName));

            return(_finalizeJobConsumerConnector.ConnectConsumer(consumePipe, consumerFactory, specification));
        }
        public JobConsumerMessageSpecification()
        {
            _submitJobSpecification = ConsumerConnectorCache <SubmitJobConsumer <TJob> > .Connector.CreateConsumerSpecification <SubmitJobConsumer <TJob> >();

            _startJobSpecification = ConsumerConnectorCache <StartJobConsumer <TJob> > .Connector.CreateConsumerSpecification <StartJobConsumer <TJob> >();

            _cancelJobSpecification = ConsumerConnectorCache <CancelJobConsumer <TJob> > .Connector.CreateConsumerSpecification <CancelJobConsumer <TJob> >();

            _consumerSpecification = new ConsumerMessageSpecification <TConsumer, TJob>();
        }
예제 #14
0
        ConnectHandle IInstanceConnector.ConnectInstance(IConsumePipeConnector pipeConnector, object instance)
        {
            if (instance is TConsumer consumer)
            {
                IConsumerSpecification <TConsumer> specification = CreateConsumerSpecification <TConsumer>();

                return(ConnectInstance(pipeConnector, consumer, specification));
            }

            throw new ConsumerException(
                      $"The instance type {TypeMetadataCache.GetShortName(instance.GetType())} does not match the consumer type: {TypeMetadataCache<TConsumer>.ShortName}");
        }
예제 #15
0
        ConnectHandle IInstanceConnector.ConnectInstance(IConsumePipeConnector pipeConnector, object instance)
        {
            var consumer = instance as TConsumer;

            if (consumer == null)
            {
                throw new ConsumerException(
                          $"The instance type {instance.GetType().GetTypeName()} does not match the consumer type: {TypeMetadataCache<TConsumer>.ShortName}");
            }

            IConsumerSpecification <TConsumer> specification = CreateConsumerSpecification <TConsumer>();

            return(ConnectInstance(pipeConnector, consumer, specification));
        }
예제 #16
0
        public ConnectHandle ConnectConsumer(IConsumePipeConnector consumePipe, IConsumerFactory <TConsumer> consumerFactory,
                                             IConsumerSpecification <TConsumer> specification)
        {
            IConsumerMessageSpecification <TConsumer, TMessage> messageSpecification = specification.GetMessageSpecification <TMessage>();

            IPipe <ConsumerConsumeContext <TConsumer, TMessage> > consumerPipe = messageSpecification.Build(_consumeFilter);

            IPipe <ConsumeContext <TMessage> > messagePipe = messageSpecification.BuildMessagePipe(x =>
            {
                x.UseFilter(new ConsumerMessageFilter <TConsumer, TMessage>(consumerFactory, consumerPipe));
            });

            return(consumePipe.ConnectConsumePipe(messagePipe));
        }
예제 #17
0
        /// <summary>
        /// Connect a consumer to the bus instance's default endpoint
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="connector"></param>
        /// <param name="consumerFactory"></param>
        /// <param name="pipeSpecifications"></param>
        /// <returns></returns>
        public static ConnectHandle ConnectConsumer<T>(this IConsumePipeConnector connector, IConsumerFactory<T> consumerFactory,
            params IPipeSpecification<ConsumerConsumeContext<T>>[] pipeSpecifications)
            where T : class, IConsumer
        {
            if (connector == null)
                throw new ArgumentNullException(nameof(connector));
            if (consumerFactory == null)
                throw new ArgumentNullException(nameof(consumerFactory));

            IConsumerSpecification<T> specification = ConsumerConnectorCache<T>.Connector.CreateConsumerSpecification<T>();
            foreach (IPipeSpecification<ConsumerConsumeContext<T>> pipeSpecification in pipeSpecifications)
            {
                specification.AddPipeSpecification(pipeSpecification);
            }
            return ConsumerConnectorCache<T>.Connector.ConnectConsumer(connector, consumerFactory, specification);
        }
        public ConnectHandle ConnectConsumer(IConsumePipeConnector consumePipe, IConsumerFactory <TConsumer> consumerFactory,
                                             IConsumerSpecification <TConsumer> specification)
        {
            var jobServiceOptions = specification.Options <JobServiceOptions>();
            var jobService        = jobServiceOptions.JobService;

            if (jobService == null || jobServiceOptions.InstanceEndpointConfigurator == null)
            {
                throw new ConfigurationException(
                          "The job service must be configured prior to configuring a job consumer, using either ConfigureJobServiceEndpoints or ConfigureJobService");
            }

            var options = specification.Options <JobOptions <TJob> >();

            var jobTypeId = jobService.GetJobTypeId <TJob>();

            IConsumerMessageSpecification <TConsumer, TJob> messageSpecification = specification.GetMessageSpecification <TJob>();

            var jobSpecification = messageSpecification as JobConsumerMessageSpecification <TConsumer, TJob>;

            if (jobSpecification == null)
            {
                throw new ArgumentException("The consumer specification did not match the message specification type");
            }

            var submitJobHandle = ConnectSubmitJobConsumer(consumePipe, jobSpecification.SubmitJobSpecification, options, jobTypeId);

            IPipe <ConsumeContext <TJob> > jobPipe = CreateJobPipe(consumerFactory, specification);
            var startJobHandle = ConnectStartJobConsumer(consumePipe, jobSpecification.StartJobSpecification, options, jobService, jobPipe);

            ConfigureStartJobConsumer(jobServiceOptions.InstanceEndpointConfigurator, options, jobService, jobPipe);

            var finalizeJobHandle = ConnectFinalizeJobConsumer(consumePipe, jobSpecification.FinalizeJobSpecification, options, jobService);

            var superviseJobHandle = ConnectSuperviseJobConsumer(consumePipe, jobSpecification.SuperviseJobSpecification, jobService);

            ConfigureSuperviseJobConsumer(jobServiceOptions.InstanceEndpointConfigurator, jobService);

            return(new MultipleConnectHandle(submitJobHandle, startJobHandle, finalizeJobHandle, superviseJobHandle));
        }
예제 #19
0
        /// <summary>
        /// Connect a consumer to the bus instance's default endpoint
        /// </summary>
        /// <typeparam name="TConsumer"></typeparam>
        /// <param name="connector"></param>
        /// <param name="consumerFactory"></param>
        /// <param name="pipeSpecifications"></param>
        /// <returns></returns>
        public static ConnectHandle ConnectConsumer <TConsumer>(this IConsumePipeConnector connector, IConsumerFactory <TConsumer> consumerFactory,
                                                                params IPipeSpecification <ConsumerConsumeContext <TConsumer> >[] pipeSpecifications)
            where TConsumer : class, IConsumer
        {
            if (connector == null)
            {
                throw new ArgumentNullException(nameof(connector));
            }
            if (consumerFactory == null)
            {
                throw new ArgumentNullException(nameof(consumerFactory));
            }

            LogContext.Debug?.Log("Connecting Consumer: {ConsumerType} (using supplied consumer factory)", TypeMetadataCache <TConsumer> .ShortName);

            IConsumerSpecification <TConsumer> specification = ConsumerConnectorCache <TConsumer> .Connector.CreateConsumerSpecification <TConsumer>();

            foreach (IPipeSpecification <ConsumerConsumeContext <TConsumer> > pipeSpecification in pipeSpecifications)
            {
                specification.AddPipeSpecification(pipeSpecification);
            }

            return(ConsumerConnectorCache <TConsumer> .Connector.ConnectConsumer(connector, consumerFactory, specification));
        }
예제 #20
0
        public ConnectHandle ConnectInstance <T>(IConsumePipeConnector pipeConnector, T instance, IConsumerSpecification <T> specification)
            where T : class
        {
            var handles = new List <ConnectHandle>();

            try
            {
                foreach (IInstanceMessageConnector <T> connector in _connectors.Cast <IInstanceMessageConnector <T> >())
                {
                    var handle = connector.ConnectInstance(pipeConnector, instance, specification);

                    handles.Add(handle);
                }

                return(new MultipleConnectHandle(handles));
            }
            catch (Exception)
            {
                foreach (var handle in handles)
                {
                    handle.Dispose();
                }
                throw;
            }
        }
예제 #21
0
        static IPipe <ConsumeContext <TJob> > CreateJobPipe(IConsumerFactory <TConsumer> consumerFactory, IConsumerSpecification <TConsumer> specification)
        {
            IConsumerMessageSpecification <TConsumer, TJob> messageSpecification = specification.GetMessageSpecification <TJob>();

            var options = specification.Options <JobOptions <TJob> >();

            var jobFilter = new JobConsumerMessageFilter <TConsumer, TJob>(options.RetryPolicy);

            IPipe <ConsumerConsumeContext <TConsumer, TJob> > consumerPipe = messageSpecification.Build(jobFilter);

            IPipe <ConsumeContext <TJob> > messagePipe = messageSpecification.BuildMessagePipe(x =>
            {
                x.UseFilter(new ConsumerMessageFilter <TConsumer, TJob>(consumerFactory, consumerPipe));
            });

            return(messagePipe);
        }