예제 #1
0
        public override Host Build()
        {
            if (ServiceBuilders.Count > 1)
            {
                throw new HostConfigurationException("A shelf can only have one service configured");
            }

            ServiceBuilder builder = ServiceBuilders.Single();

            _log.DebugFormat("[Shelf:{0}] Building Service: {1}", Description.Name, builder.Name);

            var controllerFactory = new ServiceControllerFactory();
            ActorFactory <IServiceController> factory = controllerFactory.CreateFactory(inbox =>
            {
                var publish = new PublishChannel(_channel, inbox);

                IServiceController service = builder.Build(inbox, publish);

                return(service);
            });

            ActorRef instance = factory.GetActor();

            _channel.Connect(x => x.AddChannel(instance));

            // this creates the state machine instance in the shelf and tells the servicecontroller
            // to create the service
            instance.Send(new CreateService(Description.Name));

            return(new ShelfHost(instance));
        }
        /// <summary>
        /// Publishes a message to the queue using the QueueName as the routingKey.
        /// </summary>
        /// <typeparam name="T">The type of the message object.</typeparam>
        /// <param name="msg">The message.</param>
        /// <param name="exchange">[Optional] The exchange name.</param>
        /// <param name="delayMilliseconds">[Optional] The delay milliseconds before the message is available in the queue.</param>
        private void PublishMessage <T> (T msg, string exchange, string queueName, int delayMilliseconds)
        {
            // set persistent property
            IBasicProperties basicProperties = null;

            if (_publishPersistent)
            {
                if (basicProperties == null)
                {
                    basicProperties = ConsumerChannel.CreateBasicProperties();
                }
                basicProperties.Persistent = _publishPersistent;
            }

            if (_retryDelayMilliseconds > 0)
            {
                if (basicProperties == null)
                {
                    basicProperties = ConsumerChannel.CreateBasicProperties();
                }
                basicProperties.AddHeader("x-delay", _retryDelayMilliseconds);
            }

            // publish message
            PublishChannel.BasicPublish(exchange: exchange ?? "",
                                        routingKey: queueName,
                                        basicProperties: basicProperties,
                                        body: GetMessageContent(msg));
        }
        private bool CheckRetryLimit(long retryLimit, RabbitWorkMessage msg)
        {
            IBasicProperties properties = msg.BasicProperties;

            if (retryLimit <= 0)
            {
                return(true);
            }

            // check dead-letter counter (number of times the message was dlx)
            long count = msg.GetRetryCount();

            // check dlx count against our threshold
            if (count >= retryLimit)
            {
                // move message to dead-letter queue
                if (String.IsNullOrEmpty(deadLetterQueue))
                {
                    // create dead letter queue
                    lock (QueueName)
                    {
                        deadLetterQueue = QueueName + ".dead-letter";
                        deadLetterQueue = EnsureQueueExists(deadLetterQueue, Mode);
                    }
                }
                // publish message to the deadletter queue
                PublishChannel.BasicPublish("", deadLetterQueue, (IBasicProperties)properties.Clone(), msg.Body);
                // delete message
                Ack(msg);
                return(false);
            }
            return(true);
        }
예제 #4
0
        private Task CreateConnections(IConnectionFactory factory)
        {
            try
            {
                ReadConnection  = factory.CreateConnection();
                WriteConnection = factory.CreateConnection();
            }
            catch (Exception e)
            {
                return(Task.FromException(e));
            }

            PublishChannel = WriteConnection.CreateModel();

            PublishChannel.ExchangeDeclare(Group, "direct");

            var rpcModel = GetOrCreateChannel("RPC");

            RPCQueueName = rpcModel.QueueDeclare().QueueName;

            rpcModel.QueueBind(RPCQueueName, Group, RPCQueueName);

            RPCConsumer = new EventingBasicConsumer(rpcModel);

            rpcModel.BasicConsume(RPCQueueName, AutoAck, RPCConsumer);

            return(Task.CompletedTask);
        }
예제 #5
0
        public override Host Build()
        {
            if (ServiceBuilders.Count > 1)
                throw new HostConfigurationException("A shelf can only have one service configured");

            ServiceBuilder builder = ServiceBuilders.Single();

            _log.DebugFormat("[Shelf:{0}] Building Service: {1}", Description.Name, builder.Name);

            var controllerFactory = new ServiceControllerFactory();
            ActorFactory<IServiceController> factory = controllerFactory.CreateFactory(inbox =>
                {
                    var publish = new PublishChannel(_channel, inbox);

                    IServiceController service = builder.Build(inbox, publish);

                    return service;
                });

            ActorRef instance = factory.GetActor();

            _channel.Connect(x => x.AddChannel(instance));

            // this creates the state machine instance in the shelf and tells the servicecontroller
            // to create the service
            instance.Send(new CreateService(Description.Name));

            return new ShelfHost(instance);
        }
 /// <summary>
 /// 关闭并释放通道
 /// </summary>
 public void Dispose()
 {
     if (PublishChannel.IsOpen)
     {
         PublishChannel.Close();
     }
     PublishChannel.Dispose();
 }
예제 #7
0
        /// <summary>
        ///     PublishAsync Publishes a message
        /// </summary>
        /// <param name="event">The name of the event to publish</param>
        /// <param name="data">The data of the event to publish</param>
        /// <param name="options">Optional options for this Publish</param>
        /// <returns>Task</returns>
        public Task PublishAsync(string @event, byte[] data, IBasicProperties options = null)
        {
            lock (PublishChannel)
            {
                PublishChannel.BasicPublish(Group, @event, false, options ?? new BasicProperties(),
                                            data);
            }

            return(Task.CompletedTask);
        }
예제 #8
0
        /// <summary>
        ///     Disconnect disconnects the Client from the Amqp Server.
        /// </summary>
        /// <param name="code">The status code of the disconnect.</param>
        /// <param name="text">The status text of the disconnect.</param>
        public void Disconnect(ushort code, string text)
        {
            lock (PublishChannel)
            {
                PublishChannel.Close(code, text);
            }

            foreach (var value in SubscribeChannels.Values)
            {
                value.Close();
            }
            WriteConnection.Close(code, text);
            ReadConnection.Close(code, text);
        }
예제 #9
0
        /// <summary>
        /// Publishes the specified message to the specified queue.
        /// </summary>
        /// <param name="message">Message to queue.</param>
        /// <param name="queue">Queue to place message in.</param>
        public static bool Publish(byte[] message, RabbitMqQueue queue, bool noConfirm)
        {
            PublishChannel pChannel = GetPublishChannel(queue, noConfirm);

            lock (pChannel.Lock)
            {
                IModel           channel  = pChannel.Channel;
                IBasicProperties msgProps = channel.CreateBasicProperties();
                msgProps.Persistent = true;
                channel.BasicPublish(string.Empty, GetQueueNameFromEnum(queue), true, msgProps, message);
                if (noConfirm)
                {
                    return(true);
                }

                if (!channel.WaitForConfirms())
                {
                    return(false);
                }

                return(true);
            }
        }
예제 #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="queue"></param>
        /// <returns></returns>
        public static PublishChannel GetPublishChannel(RabbitMqQueue queue, bool noConfirm)
        {
            IModel channel = GetChannel(queue);             // Ensure the Queue exists.


            if (noConfirm)
            {
                return(new PublishChannel(channel));
            }

            int threadID = Thread.CurrentThread.ManagedThreadId;

            lock (_PublishChannelsLock)
            {
                if (!_PublishChannels.ContainsKey(threadID))
                {
                    PublishChannel pChannel = new PublishChannel(LocalhostConnection.CreateModel());
                    pChannel.Channel.ConfirmSelect();
                    _PublishChannels.Add(threadID, pChannel);
                }
            }

            return(_PublishChannels[threadID]);
        }
예제 #11
0
 /// <summary>
 /// Depublishes a RealEstate object.
 /// </summary>
 /// <param name="publishChannel">The channel to depublish from.</param>
 /// <returns>
 /// The task object representing the asynchronous operation.
 /// </returns>
 public Task UnpublishAsync(PublishChannel publishChannel)
 {
     return(Publish.UnpublishAsync(RealEstate, publishChannel));
 }
예제 #12
0
 /// <summary>
 /// Depublishes a list of RealEstate objects.
 /// </summary>
 /// <param name="realEstates">The RealEstate objects.</param>
 /// <param name="publishChannel">The channel to depublish from.</param>
 public Task <PublishObjects> UnpublishAsync(IEnumerable <RealEstate> realEstates, PublishChannel publishChannel)
 {
     return(UnpublishAsync(realEstates, (int)publishChannel.Id.Value));
 }
예제 #13
0
 /// <summary>
 /// Publishes a RealEstate object.
 /// </summary>
 /// <param name="realEstate">The RealEstate object.</param>
 /// <param name="publishChannel">The channel to publish to.</param>
 /// <returns></returns>
 public Task PublishAsync(RealEstate realEstate, PublishChannel publishChannel)
 {
     return(PublishAsync(realEstate, (int)publishChannel.Id));
 }
예제 #14
0
 /// <summary>
 /// Publishes a RealEstate object.
 /// </summary>
 /// <param name="publishChannel">The channel to publish to.</param>
 /// <returns>
 /// The task object representing the asynchronous operation.
 /// </returns>
 public Task PublishAsync(PublishChannel publishChannel)
 {
     return Publish.PublishAsync(RealEstate, publishChannel);
 }
예제 #15
0
 /// <summary>
 /// Depublishes a list of RealEstate objects.
 /// </summary>
 /// <param name="realEstates">The RealEstate objects.</param>
 /// <param name="publishChannel">The channel to depublish from.</param>  
 public Task<PublishObjects> UnpublishAsync(IEnumerable<RealEstate> realEstates, PublishChannel publishChannel)
 {
     return UnpublishAsync(realEstates, (int)publishChannel.Id.Value);
 }
예제 #16
0
 /// <summary>
 /// Publishes a RealEstate object.
 /// </summary>
 /// <param name="realEstate">The RealEstate object.</param>
 /// <param name="publishChannel">The channel to publish to.</param>
 /// <returns></returns>
 public Task PublishAsync(RealEstate realEstate, PublishChannel publishChannel)
 {
     return PublishAsync(realEstate, (int)publishChannel.Id);
 }