/// <summary> /// Sends messages to network agents instructing them to update queues with /// the values presently stored in the Queue objects. Update messages for /// queues whose rate limit has not changed since the last time this routine /// was called are suppressed. The messages are sent synchronously in parallel /// and control is not returned to the caller until all network agents have replied. /// </summary> public void UpdateRateLimits() { ValidateState(RateControllerState.UpdateCallback, "UpdateRateLimits"); ManualResetEvent NetMessagesComplete = NetBeginMessagePairs(netRateController.UpdateRateLimits); MessageTypes replyType = MessageTypes.MessageTypeFlowUpdateAck; int typeIndex = (int)replyType; lock (LockPendingReplies[typeIndex]) { // // Send update messages only wrt queues whose rate limits have been changed. // foreach (Connection conn in AgentNameToConn.Values) { int countQueues = 0; foreach (OktoQueue queue in conn.ListQueues) if (queue.IsChanged) countQueues++; if (countQueues == 0) continue; OktoQueue[] arrayQosArg = new OktoQueue[countQueues]; int i = 0; foreach (OktoQueue queue in conn.ListQueues) { if (queue.IsChanged) { queue.Update(); arrayQosArg[i++] = queue; } } MessageFlowUpdate mFlowUpdate = new MessageFlowUpdate(++SeqNo, arrayQosArg); SendParallel(conn, mFlowUpdate.Serialize, replyType, mFlowUpdate.SeqNo); } WaitForParallelReplies(replyType, Parameters.DEFAULT_MESSAGE_TIMEOUT_MS); } // lock replyType = MessageTypes.MessageTypeIoFlowUpdateAck; typeIndex = (int)replyType; lock (LockPendingReplies[typeIndex]) { // // Send update messages for IoFlow queues. // Cannot filter unchanged as we don't know how to interpret free-format strings. // foreach (Connection conn in IoFlowNameToConn.Values) { if (conn.DictIoFlows.Count == 0) continue; List<Flow> listFlow = conn.DictIoFlows.Values.ToList<Flow>(); MessageIoFlowUpdate mFlowUpdate = new MessageIoFlowUpdate(++SeqNo, listFlow); SendParallel(conn, mFlowUpdate.Serialize, replyType, mFlowUpdate.SeqNo); } WaitForParallelReplies(replyType, Parameters.DEFAULT_MESSAGE_TIMEOUT_MS); } // lock NetMessagesComplete.WaitOne(); }
public static MessageIoFlowUpdate CreateFromNetBytes(byte[] buffer, int offset) { int oldOffset = offset; MessageIoFlowUpdate msg = new MessageIoFlowUpdate(); msg.Length = (uint)Utils.Int32FromNetBytes(buffer, offset); offset += 4; msg.SeqNo = (uint)Utils.Int32FromNetBytes(buffer, offset); offset += 4; msg.MessageType = buffer[offset++]; msg.ListParams = new List<IoFlowMessageParams>(); int countParams = Utils.Int32FromNetBytes(buffer, offset); offset += 4; for (int i = 0; i < countParams; i++) { IoFlowMessageParams ioFlowParams = IoFlowMessageParams.CreateFromNetBytes(buffer, offset); msg.ListParams.Add(ioFlowParams); offset += ioFlowParams.NetByteCount; } return msg; }