コード例 #1
0
ファイル: Telegraph.cs プロジェクト: Mossharbor/Telegraphy
        public bool OnMessageRecieved <T>(T msg) where T : class, IActorMessage
        {
            if (msg is ControlMessages.HangUp)
            {
                Broadcast(msg);
                UnRegisterAll();
                msg.Status?.TrySetResult(msg);
                return(true);
            }

            if (IsUsingSingleOperator())
            {
                return(MainOperator.OnMessageRecieved <T>(msg));
            }

            IOperator op = null;

            switch (this.MessageDispatchProcedure)
            {
            case MessageDispatchProcedureType.RandomSelection:
            {
                var handlesType = LocalSwitchboard.HandleValueTypeMessage(typeof(T));

                if (!msgTypeToOperator.ContainsKey(handlesType))
                {
                    throw new NoOperatorRegisteredToSupportTypeException(handlesType.ToString());
                }

                int nextIndex = rand.Next(0, msgTypeToOperator[handlesType].Count - 1);

                op = msgTypeToOperator[handlesType].ElementAt(nextIndex);
            }
            break;

            case MessageDispatchProcedureType.BroadcastToAll:
                return(Broadcast <T>(msg));

            case MessageDispatchProcedureType.RoundRobin:
            {
                var handlesType = msg.GetType();

                if (!msgTypeToOperator.ContainsKey(handlesType))
                {
                    throw new NoOperatorRegisteredToSupportTypeException(handlesType.ToString());
                }
                if (((ConcurrentQueue <IOperator>)msgTypeToOperator[handlesType]).Count == 1)
                {
                    if (!((ConcurrentQueue <IOperator>)msgTypeToOperator[handlesType]).TryPeek(out op))
                    {
                        throw new CouldNotRetrieveNextOperatorFromQueueException();
                    }
                }
                else
                {
                    if (!((ConcurrentQueue <IOperator>)msgTypeToOperator[handlesType]).TryDequeue(out op))
                    {
                        throw new CouldNotRetrieveNextOperatorFromQueueException();
                    }

                    //Re-Add the operator to the bottom of the queue.
                    ((ConcurrentQueue <IOperator>)msgTypeToOperator[handlesType]).Enqueue(op);
                }
            }
            break;

            case MessageDispatchProcedureType.LeastBusy:
            {
                var handlesType = LocalSwitchboard.HandleValueTypeMessage(typeof(T));

                if (!msgTypeToOperator.ContainsKey(handlesType))
                {
                    throw new NoOperatorRegisteredToSupportTypeException(handlesType.ToString());
                }

                ulong leastCount = ulong.MaxValue;
                for (int i = msgTypeToOperator[handlesType].Count - 1; i >= 0 && i < msgTypeToOperator[handlesType].Count; --i)
                {
                    IOperator tempOp = msgTypeToOperator[handlesType].ElementAt(i);

                    if (leastCount > tempOp.Count)
                    {
                        leastCount = tempOp.Count;
                        op         = tempOp;
                    }

                    if (0 == tempOp.Count)
                    {
                        break;
                    }
                }
            }
            break;

            default:
                throw new UnsupportedDispatchImplementationException();
            }

            return(op.OnMessageRecieved <T>(msg));
        }