private void MapTypeToOperator <T>(IOperator op) { var handlesType = LocalSwitchboard.HandleValueTypeMessage(typeof(T)); if (!msgTypeToOperator.ContainsKey(handlesType)) { if (this.MessageDispatchProcedure == MessageDispatchProcedureType.RoundRobin) { if (!msgTypeToOperator.TryAdd(handlesType, new ConcurrentQueue <IOperator>())) { throw new FailedToRegisterOperatorForTypeException(this.MessageDispatchProcedure.ToString() + ":" + handlesType.ToString()); } } else { if (!msgTypeToOperator.TryAdd(handlesType, new ConcurrentBag <IOperator>())) { throw new FailedToRegisterOperatorForTypeException(this.MessageDispatchProcedure.ToString() + ":" + handlesType.ToString()); } } } if (this.MessageDispatchProcedure == MessageDispatchProcedureType.RoundRobin) { ((ConcurrentQueue <IOperator>)msgTypeToOperator[handlesType]).Enqueue(op); } else { if (msgTypeToOperator[handlesType].TryAdd(op)) { throw new FailedToRegisterOperatorForTypeException(handlesType.ToString()); } } }
public void Register <K>(System.Linq.Expressions.Expression <Func <object, K> > msgCreationFunction) where K : IActorMessage { var func = msgCreationFunction.Compile(); var invoker = new ActorMessageInvocation <K>(func); var msgType = LocalSwitchboard.HandleValueTypeMessage(typeof(K)); _msgTypeToInstatiation.TryAdd(msgType, invoker); }
public void Register <T>(Action <T> action) where T : class { IActor anonActor = new AnonActor <T>(action); ILocalSwitchboard switchBoard = new LocalSwitchboard(LocalConcurrencyType.OneActorPerThread); switchBoard.Operator = this.Operator; _actorToSwitchBoard.TryAdd(anonActor.GetType(), switchBoard); switchBoard.Register(action); foreach (var t in _exceptionTypeToHandler) { switchBoard.Register(t.Key, t.Value); } // for each T we create a new LocalSwitchboard that only operates on that type T }
public void Register <T, K>(Expression <Func <K> > factory) where K : IActor { Type typeOfActor = typeof(K); if (_actorToSwitchBoard.ContainsKey(typeOfActor)) { throw new ActorHasAlreadyBeenRegisteredException(); } ILocalSwitchboard switchBoard = new LocalSwitchboard(LocalConcurrencyType.OneActorPerThread); switchBoard.Operator = this.Operator; _actorToSwitchBoard.TryAdd(typeOfActor, switchBoard); switchBoard.Register <T, K>(factory); foreach (var t in _exceptionTypeToHandler) { switchBoard.Register(t.Key, t.Value); } }
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)); }