public void PostAlert(OktoAlertType alertType, ulong[] args)
 {
     // Push message to the sequential work queue for upcall into Policy Module.
     MessageAlert mAlert = new MessageAlert(alertType,args);
     RcWorkItem rcWorkItem = new RcWorkItem(RcWorkItemType.Alert, mAlert, 0, null);
     RcWorkQueue.Enqueue(rcWorkItem);
 }
 public void PostAlertMessage(byte[] buffer, int offset)
 {
     // Parse and push message to the sequential work queue for upcall into Policy Module.
     MessageAlert mAlert = MessageAlert.CreateFromNetBytes(buffer,offset);
     RcWorkItem rcWorkItem = new RcWorkItem(RcWorkItemType.Alert, mAlert, 0, null);
     RcWorkQueue.Enqueue(rcWorkItem);
 }
 public void CallbackAlert(MessageNetAlert netAlert, NetRateControllerState state)
 {
     //
     // Turn the network alert into an oktofs alert and post it to work item queue for dispatch to policy module.
     //
     //throw new NotImplementedException("OktofsRateController CallbackAlert should never get called.");
     MessageAlert mAlert = MessageAlert.CreateFromNetAlert(netAlert);
     Log(String.Format("netAlert {0}", netAlert));
     RcWorkItem rcWorkItem = new RcWorkItem(RcWorkItemType.Alert, mAlert, 0, null);
     RcWorkQueue.Enqueue(rcWorkItem);
 }
 /// <summary>
 /// Starts the Timeout timer.
 /// </summary>
 /// <param name="dueTime"></param>
 private void StartTimer(long millisecsFromNow, RcWorkItem context)
 {
     lock (LockTimer)
     {
         CurrentTimeoutUSecs = softTimer.TimeNowUSecs() + (millisecsFromNow * 1000);
         context.TimerUSecs = CurrentTimeoutUSecs;
         softTimer.RegisterTimer(CurrentTimeoutUSecs, context);
     }
 }
 /// <summary>
 /// Single thread running work queue service routine ensures sequential callbacks into Policy Module.
 /// </summary>
 /// <param name="workItem"></param>
 private void RunRcWorkQueueItem(RcWorkItem workItem)
 {
     switch (workItem.Type)
     {
         case RcWorkItemType.SettleTimeout:
             if (IsCurrentTimeout(workItem.TimerUSecs))
             {
                 StateTransition(RateControllerState.SettleCallback);
                 StateTransition(RateControllerState.SampleTimeout);
             }
             else
             {
                 smsg("ignore stale TO IntervalSettleExpired");
             }
             break;
         case RcWorkItemType.SampleTimeout:
             if (IsCurrentTimeout(workItem.TimerUSecs))
             {
                 StateTransition(RateControllerState.UpdateCallback);
                 StateTransition(RateControllerState.SettleTimeout);
             }
             else
             {
                 smsg("ignore stale TO IntervalSampleExpired");
             }
             break;
         case RcWorkItemType.Alert:
             // Note: the alert callback may (have to) adjust current RC state.
             iPolicyModule.CallbackAlert((MessageAlert)workItem.Args, State);
             break;
     }
 }
        /// <summary>
        /// Transitions state machine. Called from sequential work queue in response to timeouts and alerts. 
        /// </summary>
        /// <param name="nextState"></param>
        public void StateTransition(RateControllerState nextState)
        {
            RcWorkItem context;
            lock (LockState)
            {
                Debug.WriteLine("StateTransition {0}=>{1}", state, nextState);
                if (state.Equals(RateControllerState.Fin) ||
                    nextState.Equals(RateControllerState.Fin) ||
                    Shutdown)
                {
                    state = RateControllerState.Fin;
                    return;
                }

                //
                // Transition to new state and take the actions associated with that state.
                //
                switch (state)
                {
                    case RateControllerState.Init:
                        Debug.Assert(nextState == RateControllerState.SettleTimeout);
                        state = nextState;
                        if (netRateController != null)
                            netRateController.StateTransitionNoOp(NetRateControllerState.SettleTimeout);
                        context = new RcWorkItem(RcWorkItemType.SettleTimeout, RateControllerState.SettleTimeout, settleMillisecs, null);
                        Console.WriteLine("RateController start init timer {0} millisecs", RcWorkItemType.SettleTimeout);
                        StartTimer(settleMillisecs, context);
                        break;
                    case RateControllerState.SettleTimeout:
                        Debug.Assert(nextState == RateControllerState.SettleCallback);
                        state = nextState;
                        if (netRateController != null)
                            netRateController.StateTransitionNoOp(NetRateControllerState.SettleCallback);
                        iPolicyModule.CallbackSettleTimeout();
                        break;
                    case RateControllerState.SettleCallback:
                        Debug.Assert(nextState == RateControllerState.SampleTimeout);
                        state = nextState;
                        if (netRateController != null)
                            netRateController.StateTransitionNoOp(NetRateControllerState.SampleTimeout);
                        context = new RcWorkItem(RcWorkItemType.SampleTimeout, RateControllerState.SampleTimeout, sampleMillisecs, null);
                        StartTimer(sampleMillisecs, context);
                        break;
                    case RateControllerState.SampleTimeout:
                        Debug.Assert(nextState == RateControllerState.UpdateCallback);
                        state = nextState;
                        if (netRateController != null)
                            netRateController.StateTransitionNoOp(NetRateControllerState.UpdateCallback);
                        iPolicyModule.CallbackControlInterval();
                        break;
                    case RateControllerState.UpdateCallback:
                        Debug.Assert(nextState == RateControllerState.SettleTimeout);
                        state = nextState;
                        if (netRateController != null)
                            netRateController.StateTransitionNoOp(NetRateControllerState.SettleTimeout);
                        context = new RcWorkItem(RcWorkItemType.SettleTimeout, RateControllerState.SettleTimeout, settleMillisecs, null);
                        StartTimer(settleMillisecs, context);
                        break;
                }
            }
        }
        /// <summary>
        /// Called by a connection when it has received an intact and complete message in wire-format.
        /// Parses the supplied byte-array to generate a typed message for processing.
        /// On return from this routine the connection is free to overwrite the buffer contents.
        /// /// </summary>
        /// <param name="conn">Connection (think TCP to specific network agent) on which message arrived.</param>
        /// <param name="buff">Buffer encoding the message.</param>
        /// <param name="offset">Offset to start of message in the supplied buffer.</param>
        /// <param name="length">Length of message encoding in supplied buffer</param>
        public void ReceiveMessage(Connection conn, MessageTypes messageType, byte[] buff, int offset, int length)
        {
            bool unblock = false;
            switch (messageType)
            {
                case MessageTypes.MessageTypeAck:
                    {
                        conn.MessageAck.InitFromNetBytes(buff, 0);
                        //Console.WriteLine("SendParallel rcv MessageAck({0},{1})", conn.MessageAck.SeqNo, conn.MessageAck.Result);
                        if (conn.MessageAck.Result != (uint)OktoResultCodes.OKTO_RESULT_SUCCESS)
                        {
                            string msg = String.Format("ACK err: conn {0} ResultCode {1} subytpe {2}",
                                conn.HostName, conn.MessageAck.Result, (MessageTypes)conn.MessageAck.SubType);
                            Console.WriteLine(msg);
                        }
                        MessageTypes AckSubType = (MessageTypes)conn.MessageAck.SubType;
                        unblock = DowndatePendingReplies(AckSubType, conn.MessageAck.SeqNo);
                        conn.BeginReceive();
                        break;
                    }

                case MessageTypes.MessageTypeStatsReplyDelta:
                    {
                        MessageStatsReplyDelta mStatsDelta = MessageStatsReplyDelta.CreateFromNetBytes(conn.receiveBuffer, 0, conn, this);
                        //Console.WriteLine("ReceiveRaw MessageStatsReplyDelta({0},{1})", mStatsDelta.SeqNo, mStatsDelta.Result);
                        ulong intervalUSecs = mStatsDelta.IntervalUSecs;

                        foreach (KeyValuePair<ushort, FlowStats> kvp in mStatsDelta.dictFlowStats)
                        {
                            RAP rap = conn.ListRap[kvp.Key];
                            FlowStats flowStats = kvp.Value;
                            rap.SetFlowStats(flowStats);
                        }
                        unblock = DowndatePendingReplies(messageType, mStatsDelta.SeqNo);
                        conn.BeginReceive();
                        break;
                    }

                case MessageTypes.MessageTypeNameToStringSidReply:
                    {
                        MessageVmNameToStringSidReply mNameToSidReply
                            = MessageVmNameToStringSidReply.CreateFromNetBytes(conn.receiveBuffer, 0);
                        string vmKey = conn.HostName + "." + mNameToSidReply.VmName;
                        lock (DictVmNameToSid)
                        {
                            if (!DictVmNameToSid.ContainsKey(vmKey))
                                DictVmNameToSid.Add(vmKey, mNameToSidReply.SidString);
                        }
                        unblock = DowndatePendingReplies(messageType, mNameToSidReply.SeqNo);
                        conn.BeginReceive();
                        break;
                    }

                case MessageTypes.MessageTypeAlert:
                    {
                        MessageAlert mAlert = MessageAlert.CreateFromNetBytes(conn.receiveBuffer, 0);
                        //Console.WriteLine("ReceiveMessage rx alert {0}", mAlert);
                        // Push message to the sequential work queue for upcall into Policy Module.
                        RcWorkItem rcWorkItem = new RcWorkItem(RcWorkItemType.Alert, mAlert, 0, conn);
                        RcWorkQueue.Enqueue(rcWorkItem);
                        conn.BeginReceive();
                        break;
                    }

                case MessageTypes.MessageTypeIoFlowStatsReply:
                    {
                        MessageIoFlowStatsReply mIoFlowStats =
                            MessageIoFlowStatsReply.CreateFromNetBytes(conn.receiveBuffer, 0);
                        foreach (IoFlowMessageParams stats in mIoFlowStats.ListParams)
                            conn.DictIoFlows[stats.FlowId].RapD.SetIoFlowStats(stats.ParameterString);
                        unblock = DowndatePendingReplies(messageType, mIoFlowStats.SeqNo);
                        conn.BeginReceive();
                        break;
                    }

                case MessageTypes.MessageTypeNameToStringSidBatchReply:
                    {
                        MessageVmNameToStringSidBatchReply mNameToSidReply
                            = MessageVmNameToStringSidBatchReply.CreateFromNetBytes(conn.receiveBuffer, 0);
                        lock (DictVmNameToSid)
                        {
                            foreach (KeyValuePair<string, string> kvp in mNameToSidReply.DictVmNameToSid)
                            {
                                string vmKey = MakeVmKey(conn.hostName, kvp.Key);
                                if (!DictVmNameToSid.ContainsKey(vmKey))
                                {
                                    Console.WriteLine("sidBatchReply adding ({0},{1}", vmKey, kvp.Value);
                                    DictVmNameToSid.Add(vmKey, kvp.Value);
                                }
                            }
                        }
                        unblock = DowndatePendingReplies(messageType, mNameToSidReply.SeqNo);
                        conn.BeginReceive();
                        break;
                    }

                default:
                    {
                        string msg = string.Format("SendParallel: unexpected message type {0}", messageType);
                        throw new ApplicationException(msg);
                    }
                //break;
            }
        }