static void BasicDiners() { // We can model this much of a philosopher’s behavior with the following behavior definitions //These will fail, due to the LocalOperator does not enforce one message at a time per actor //var localOperator = new LocalOperator(new LocalSwitchboard(LocalConcurrencyType.ThreadPool)); //var localOperator = new LocalOperator(new LocalSwitchboard(LocalConcurrencyType.PreAllocatedThreads, 10)); // This will not work because we have the same Philosopher processing messages on both threads. //var localOperator = new SingleThreadPerMessageTypeOperator(); // this only processes on a single thread so this will succeed because message execution order is // guaranteed. However this can be non-optimal for many scenarios with lots of Actors and messages. // since all actors and messages share the same thread. //var localOperator = new LocalOperator(new LocalSwitchboard(LocalConcurrencyType.Sequential)); var localOperator = new LocalQueueOperator(new LocalSwitchboard(LocalConcurrencyType.OneThreadPerActor)); Telegraph.Instance.Register(localOperator); var t = new UnculturedPhilosopher(); Telegraph.Instance.Register <EatingMessage, UnculturedPhilosopher>(() => t); Telegraph.Instance.Register <ThinkingMessage, UnculturedPhilosopher>(() => t); Telegraph.Instance.Register <PrintMessage, UnculturedPhilosopher>(() => t); StartContimplativeGluttonousLoop(new TimeSpan(0, 0, 0, 0, 300)); // Generate messages for 50ms }
public void TestSendingStringToHybridConnectionSwitchboard() { string connectionName = "TestSendingStringToHybridConnectionSwitchboard"; string responseMessage = "Well hello to you!!"; CreateHybridConnection(connectionName); HybridConnectionListener listener = null; try { listener = CreateHybridListener(connectionName, responseMessage); ILocalSwitchboard switchBoard = new Telegraphy.Azure.Relay.Hybrid.HybridConnectionSwitchboard(3, Connections.HybridRelayConnectionString, connectionName); IOperator localOP = new LocalQueueOperator(switchBoard); Telegraph.Instance.Register(localOP); Telegraph.Instance.Register(typeof(Exception), FailOnException); // We want to send the byte[] to the localOP which will forward calls to the hybrid connection switchboard operator Telegraph.Instance.Register <string>(localOP); string responseString = (string)Telegraph.Instance.Ask("Foo").Result.Message; Assert.IsTrue(responseString.Equals(responseMessage)); } finally { Telegraph.Instance.UnRegisterAll(); try { listener?.CloseAsync().Wait(); } catch (Exception) { } DeleteHybridConnection(connectionName); } }
public void RegisterTypeAndOperator() { Telegraph.Instance.UnRegisterAll(); LocalQueueOperator op = new LocalQueueOperator(new TestSwitchBoard()); long operatorID = Telegraph.Instance.Register <string>(op); string message = "RegisterTypeAndOperator"; Telegraph.Instance.Tell(message); // We dont have an actor registered so we will this message will never be processed // however it should never throw an exception with the test switch board }
public void RegisterOperatorOnly() { Telegraph.Instance.UnRegisterAll(); LocalQueueOperator op = new LocalQueueOperator(); long operatorID = Telegraph.Instance.Register(op); string message = "RegisterOperatorOnly"; Telegraph.Instance.Tell(message); // We dont have an actor registered so we will this message will never be processed // however it should never throw an exception }
public static void RegisterActorsAndMessages(uint numberOfSimultaneousConnections) { IOperator connectionOperator = new LocalQueueOperator(new LocalSwitchboard(LocalConcurrencyType.DedicatedThreadCount, 4)); IOperator responseOperator = new LocalQueueOperator(new LocalSwitchboard(LocalConcurrencyType.ActorsOnThreadPool)); IOperator perConnection = new LocalQueueOperator(new LocalSwitchboard(LocalConcurrencyType.DedicatedThreadCount, numberOfSimultaneousConnections)); try { Telegraph.Instance.MessageDispatchProcedure = MessageDispatchProcedureType.RoundRobin; Telegraph.Instance.Register(connectionOperator); Telegraph.Instance.Register(responseOperator); Telegraph.Instance.Register(perConnection); long opID = perConnection.ID; long connID = connectionOperator.ID; long respID = responseOperator.ID; //Telegraph.Instance.MainOperator = new LocalOperator(new LocalSwitchboard(LocalConcurrencyType.ActorsOnThreadPool)); Telegraph.Instance.Register <Messages.ConnectToServer, Actors.ConnectionHandler>(connID, () => new Actors.ConnectionHandler()); Telegraph.Instance.Register <Messages.GetReponse, Actors.ResponseHandler>(respID, () => new Actors.ResponseHandler()); Telegraph.Instance.Register <Messages.DisconnectFromServer, Actors.ConnectionHandler>(connID, () => new Actors.ConnectionHandler()); Telegraph.Instance.Register <Messages.Authenticate, Actors.AuthenticateUser>(opID, () => new Actors.AuthenticateUser()); Telegraph.Instance.Register <Messages.PopulateCommandList, Actors.PopulateCommandList>(opID, () => new Actors.PopulateCommandList()); Telegraph.Instance.Register <Messages.RequestSlaveStatus, Actors.SlaveStatusHandler>(opID, () => new Actors.SlaveStatusHandler()); Telegraph.Instance.Register <Messages.ListNewsGroups, Actors.ListNewsGroupsHander>(opID, () => new Actors.ListNewsGroupsHander()); Telegraph.Instance.Register <Messages.ListNewsGroupsSince, Actors.ListNewsGroupsHander>(opID, () => new Actors.ListNewsGroupsHander()); Telegraph.Instance.Register <Messages.GetArticleHead, Actors.ArticleRetrievalHander>(opID, () => new Actors.ArticleRetrievalHander()); Telegraph.Instance.Register <Messages.GetArticleBody, Actors.ArticleRetrievalHander>(opID, () => new Actors.ArticleRetrievalHander()); Telegraph.Instance.Register <Messages.GetArticle, Actors.ArticleRetrievalHander>(opID, () => new Actors.ArticleRetrievalHander()); Telegraph.Instance.Register <Messages.PostArticle, Actors.ArticlePostHandler>(opID, () => new Actors.ArticlePostHandler()); Telegraph.Instance.Register <string>(connectionOperator.ID, message => { lock (consoleLock) { Console.WriteLine(message.Replace(System.Environment.NewLine, "")); } }); } catch (FailedRegistrationException ex) { Console.ForegroundColor = ConsoleColor.Red; Console.Error.WriteLine(ex.GetType().ToString() + ":" + ex.Message); Console.ResetColor(); throw; } RegisterErrorHandling(perConnection.ID); RegisterErrorHandling(connectionOperator.ID); }
static void CulturedDiners() { // modify the philosopher’s behavior to include a state transition through “hungry”, where chopsticks are obtained before eating. // the philosophers must send an AquireChopstick message to the InfiiteChopstick Actor (and receive a response) before they can eat. var localOperator = new LocalQueueOperator(new LocalSwitchboard(LocalConcurrencyType.OneThreadPerActor)); Telegraph.Instance.Register(localOperator); var t = new CulturedPhilosopher(); Telegraph.Instance.Register <EatingMessage, CulturedPhilosopher>(() => t); Telegraph.Instance.Register <ThinkingMessage, CulturedPhilosopher>(() => t); Telegraph.Instance.Register <PrintMessage, CulturedPhilosopher>(() => t); Telegraph.Instance.Register <AcquireChopstick, InfiniteChopstickContainer>(() => new InfiniteChopstickContainer()); StartContimplativeGluttonousLoop(new TimeSpan(0, 0, 0, 0, 10)); // Generate messages for 10ms }
public void VerifyRegisterOfDefaultSwitchBoardWithoutActorThrowsException() { try { Telegraph.Instance.UnRegisterAll(); LocalQueueOperator op = new LocalQueueOperator(); long operatorID = Telegraph.Instance.Register <string>(op); string message = "VerifyRegisterOfDefaultSwitchBoardWithoutActorThrowsException"; Telegraph.Instance.Tell(message); Assert.IsTrue(false); // we expected this exception } catch (SwitchBoardRequiresARegisteredActorOrActionException ex) { Assert.IsTrue(true); // we expected this exception } }
public void RegisterTypeActionAndOperatorByOpID() { Telegraph.Instance.UnRegisterAll(); string message = "RegisterTypeActionAndOperatorByOpID"; bool called = false; LocalQueueOperator op = new LocalQueueOperator(); long operatorID = Telegraph.Instance.Register(op); Telegraph.Instance.Register <string>(operatorID, (data) => { Assert.IsTrue(data.Equals(message)); called = true; }); Telegraph.Instance.Ask(message).Wait(); Assert.IsTrue(called); }
public static void MultipleOperatorsBasic() { int msgCount = 0, strCount = 0; try { LocalQueueOperator threadPoolOperator = new LocalQueueOperator(new LocalSwitchboard(LocalConcurrencyType.ActorsOnThreadPool)); LocalQueueOperator singleThreadOperator = new LocalQueueOperator(new LocalSwitchboard(LocalConcurrencyType.OneThreadAllActors)); Telegraph.Instance.MessageDispatchProcedure = MessageDispatchProcedureType.RoundRobin; long threadPoolOpID = Telegraph.Instance.Register(threadPoolOperator); long singleThreadOperatorID = Telegraph.Instance.Register(singleThreadOperator); //NOTE: this sets the operator ID (singleThreadOperator.ID) Telegraph.Instance.Register <string>(threadPoolOpID, message => { Console.WriteLine(System.Environment.NewLine + message); strCount++; }); Telegraph.Instance.Register <ValueTypeMessage <int> >(threadPoolOpID, count => { Console.Write((int)count.Message + ","); ++msgCount; }); } catch (FailedRegistrationException ex) { Console.ForegroundColor = ConsoleColor.Red; Console.Error.WriteLine(ex.GetType().ToString() + ":" + ex.Message); Console.ResetColor(); throw; } List <Task <IActorMessage> > msgsToWaitOn = new List <Task <IActorMessage> >(); for (int i = 0; i < 100; ++i) { if (i % 10 == 0) { // these will happen at random since we are running strings on the thread pool Telegraph.Instance.Tell <string>("MultipleOperatorsBasic:" + i.ToString()); } // this should be sequential since we are on one thread for ints msgsToWaitOn.Add(Telegraph.Instance.Ask(i.ToActorMessage())); } Task.WaitAll(msgsToWaitOn.ToArray()); Console.WriteLine(System.Environment.NewLine + "MultipleOperatorsBasic finished"); System.Diagnostics.Debug.Assert(10 == strCount); System.Diagnostics.Debug.Assert(100 == msgCount); }
public void RegisterMessageToActorByOp() { Telegraph.Instance.UnRegisterAll(); string message = "RegisterMessageToActorByOp"; bool called = false; LocalQueueOperator op = new LocalQueueOperator(); DefaultActor da = new DefaultActor(); Telegraph.Instance.Register <string, DefaultActor>(op, () => da); da.OnMessageHandler = (msg) => { called = true; Assert.IsTrue(msg.Message.Equals(message)); return(true); }; Telegraph.Instance.Ask(message.ToActorMessage()).Wait(); Assert.IsTrue(called); }
public void RegisterValueTypeToActor() { Telegraph.Instance.UnRegisterAll(); int message = 1; bool called = false; LocalQueueOperator op = new LocalQueueOperator(); long operatorID = Telegraph.Instance.Register(op); DefaultActor da = new DefaultActor(); Telegraph.Instance.Register <ValueTypeMessage <int>, DefaultActor>(operatorID, () => da); da.OnMessageHandler = (msg) => { called = true; Assert.IsFalse(!msg.Message.Equals(message)); return(true); }; Telegraph.Instance.Ask(message.ToActorMessage()).Wait(); Assert.IsTrue(called); }
public static void LimitedThreadPool() { int msgCount = 0; var localOperator = new LocalQueueOperator(new LocalSwitchboard(LocalConcurrencyType.ActorsOnThreadPool, 2)); Telegraph.Instance.Register(localOperator); Telegraph.Instance.Register <string>(message => { ++msgCount; Console.WriteLine(message); }); for (int i = 0; i < 10; ++i) { Telegraph.Instance.Tell("LimitedThreadPool was executed." + i.ToString()); } Telegraph.Instance.MainOperator.WaitTillEmpty(new TimeSpan(1, 0, 0)); System.Threading.Thread.Sleep(100); // wait for items in the queue to be processed. System.Diagnostics.Debug.Assert(10 == msgCount); }
public static void BroadcastToAllOperators() { int op1Count = 0, op2Count = 0; try { LocalQueueOperator op1 = new LocalQueueOperator(new LocalSwitchboard(LocalConcurrencyType.OneThreadAllActors)); LocalQueueOperator op2 = new LocalQueueOperator(new LocalSwitchboard(LocalConcurrencyType.OneThreadAllActors)); Telegraph.Instance.MessageDispatchProcedure = MessageDispatchProcedureType.RoundRobin; long op1ID = Telegraph.Instance.Register(op1); long op2ID = Telegraph.Instance.Register(op2); //NOTE: this sets the operator ID (op2.ID) // register a string for two different operators Telegraph.Instance.Register <string>(op1ID, message => { Console.WriteLine("1." + message); ++op1Count; }); Telegraph.Instance.Register <string>(op2ID, message => { Console.WriteLine("2." + message); ++op2Count; }); } catch (FailedRegistrationException ex) { Console.ForegroundColor = ConsoleColor.Red; Console.Error.WriteLine(ex.GetType().ToString() + ":" + ex.Message); Console.ResetColor(); throw; } for (int i = 0; i < 10; ++i) { // this should be sequential since we are on one thread for ints Telegraph.Instance.Broadcast <string>(i.ToString()); } //Task.WaitAll(msgsToWaitOn.ToArray()); Telegraph.Instance.WaitTillEmpty(new TimeSpan(0, 1, 0)); Console.WriteLine(System.Environment.NewLine + "MultipleOperatorsBasic finished"); System.Diagnostics.Debug.Assert(10 == op1Count); System.Diagnostics.Debug.Assert(10 == op2Count); }