protected void ConsumeMessageContext(IMessageContext commandContext) { _Logger.InfoFormat("send to consumer, commandID:{0} payload:{1}", commandContext.MessageID, commandContext.ToJson()); CommandQueueConsumer consumer; var commandState = new CommandState { CommandID = commandContext.MessageID, FromEndPoint = commandContext.FromEndPoint }; if (!string.IsNullOrWhiteSpace(ReceiveEndPoint)) { commandContext.FromEndPoint = this.ReceiveEndPoint; } if (!string.IsNullOrWhiteSpace(commandContext.Key)) { // 取出command的linear key, 作为consumer的选择索引 var linearKey = commandContext.Key; LinearCommandConsumer linearCommandConsumer; // 尝试从字典中取出linearkey族command的当前consumer if (!LinearCommandStates.TryGetValue(linearKey, out linearCommandConsumer)) { // linearkey对应的consumer不存在,说明没有任何consumer在消费该linearkey族的command // 此时选用负载最轻的consumer作为当前command的consumer, 并且被选中的consumer成为 // 该linearkey族command的LinearCommandConsumer, 并加入字典中. consumer = CommandConsumers.OrderBy(c => c.Payload).FirstOrDefault(); linearCommandConsumer = new LinearCommandConsumer(consumer, linearKey); LinearCommandStates.Add(linearKey, linearCommandConsumer); } else { // 根据linearKey, 从consumers中取出正在处理该linearkey族command的 // consumer作为当前command的消费者 consumer = linearCommandConsumer.CommandConsumer; } // 记录command的Consumer commandState.LinearCommandConsumer = linearCommandConsumer; // 将command 发给对应的 LinearCommandConsumer linearCommandConsumer.PushCommandContext(commandContext); } else { // 非linearcommand直接选择负载最轻的consumer 进行发送. consumer = CommandConsumers.OrderBy(c => c.Payload).FirstOrDefault(); if (consumer != null) { // 将command 发给选中的consumer consumer.PushMessageContext(commandContext); } } // 记录command在哪个consumer上处理 commandState.CommandConsumer = consumer; // 记录command的执行状态, 当reply到来时会取出并更新consumer的状态 CommandStateQueue.Add(commandContext.MessageID, commandState); }
public override void Start() { base.Start(); TargetEndPoints.ForEach(targetEndPoint => { var commandSender = ZeroMessageQueue.ZmqContext.CreateSocket(SocketType.PUSH); commandSender.Connect(targetEndPoint); CommandConsumers.Add(new CommandQueueConsumer(commandSender)); }); }
public override string GetStatus() { StringBuilder status = new StringBuilder(); status.Append("Consumer status:<br>"); lock (this) { CommandConsumers.ForEach(consumer => { status.AppendFormat("Consumer({0}):{1}/done:{2}<br>", consumer.CommandSender.LastEndpoint, consumer.Payload, consumer.FinishedCount); }); status.Append("Linear Command Status: <br>"); LinearCommandStates.ForEach(linearCommandState => { status.AppendFormat("LinearKey:{0} Consumer({1}):{2}/done:{3} <br>", linearCommandState.Key, linearCommandState.Value.CommandConsumer.CommandSender.LastEndpoint, linearCommandState.Value.Payload, linearCommandState.Value.FinishedCount); }); } return(status.ToString()); }