/// <summary> /// Represents the Start method /// </summary> /// <param name="args">Command line arguments</param> /// <exception cref="ArgumentException">Exception if arguments are not passed correctly</exception> public void Start(string[] args) { ActorSbConfig cfg = new ActorSbConfig(); var builder = new ConfigurationBuilder(); builder.AddCommandLine(args); builder.AddEnvironmentVariables(); IConfigurationRoot configArgs = builder.Build(); cfg.SbConnStr = configArgs["SbConnStr"]; // TODO: This is chetan's(FRAUAS student) storage connection string. We need to change it before commiting cfg.TblStoragePersistenConnStr = "DefaultEndpointsProtocol=https;AccountName=dotnetactors;AccountKey=mGLCq7CHPfy6Ivp23iU3hdDqGvEmyBxVAUkU1b89YeKVWKAHry3CTM7N7orGV0XCmhXdv0z7CgfYxh0MMj30Eg==;TableEndpoint=https://dotnetactors.table.cosmos.azure.com:443/;"; //NOTE: providing right above // cfg.TblStoragePersistenConnStr = configArgs["TblStoragePersistenConnStr"]; string rcvQueue = configArgs["ReplyMsgQueue"]; if (!String.IsNullOrEmpty(rcvQueue)) throw new ArgumentException("ReplyMsgQueue must not be specified when starting the server."); cfg.RequestMsgTopic = configArgs["RequestMsgTopic"]; cfg.ActorSystemName = configArgs["ActorSystemName"]; cfg.RequestSubscriptionName = configArgs["SubscriptionName"]; string systemName = configArgs["SystemName"]; Console.CancelKeyPress += (sender, eventArgs) => { tokenSrc.Cancel(); }; TableStoragePersistenceProvider prov = null; if (String.IsNullOrEmpty(cfg.TblStoragePersistenConnStr) == false) { prov = new TableStoragePersistenceProvider(); prov.InitializeAsync(cfg.ActorSystemName, new Dictionary<string, object>() { { "StorageConnectionString", cfg.TblStoragePersistenConnStr } }, purgeOnStart: false, logger: this.logger).Wait(); } akkaClusterSystem = new ActorSystem($"{systemName}", cfg, logger, prov); akkaClusterSystem.Start(tokenSrc.Token); Console.WriteLine("Press any key to stop Actor SB system."); }
public ActorSystem(string name, ActorSbConfig config, ILogger logger = null, IPersistenceProvider persistenceProvider = null) { this.logger = logger; this.persistenceProvider = persistenceProvider; this.Name = name; this.sbConnStr = config.SbConnStr; this.subscriptionName = config.RequestSubscriptionName; this.config = config; //this.sessionRcvClient = new SessionClient(config.SbConnStr, $"{config.RequestMsgTopic}/Subscriptions/{config.RequestSubscriptionName}", //retryPolicy: createRetryPolicy(), //receiveMode: ReceiveMode.PeekLock); this.sendRequestClient = new TopicClient(config.SbConnStr, config.RequestMsgTopic, retryPolicy: createRetryPolicy()); // // Receiving of reply messages is optional. If the actor system does not send messages // then it will also not listen for reply messages. if (config.ReplyMsgQueue != null) { ReplyMsgReceiverQueueClient = new QueueClient(config.SbConnStr, config.ReplyMsgQueue, retryPolicy: createRetryPolicy(), receiveMode: ReceiveMode.PeekLock); // Configure the message handler options in terms of exception handling, number of concurrent messages to deliver, etc. var messageHandlerOptions = new MessageHandlerOptions(ExceptionReceivedHandler) { // Maximum number of concurrent calls to the callback ProcessMessagesAsync(), set to 1 for simplicity. // Set it according to how many messages the application wants to process in parallel. MaxConcurrentCalls = 1, MaxAutoRenewDuration = this.MaxProcessingTimeOfMessage, // Indicates whether the message pump should automatically complete the messages after returning from user callback. // False below indicates the complete operation is handled by the user callback as in ProcessMessagesAsync(). AutoComplete = true }; // Register the function that receives reply messages. ReplyMsgReceiverQueueClient.RegisterMessageHandler(OnReplyMessageReceivedAsync, messageHandlerOptions); } }