private static Operation <Deployment, CreateDeploymentMetadata> CreateSimPlayerDeploymentAsync(DeploymentServiceClient deploymentServiceClient, string projectName, string assemblyName, string runtimeVersion, string mainDeploymentName, string simDeploymentName, string simDeploymentJsonPath, string simDeploymentSnapshotPath, string regionCode, string clusterCode, int numSimPlayers, bool useChinaPlatform) { var snapshotServiceClient = SnapshotServiceClient.Create(GetApiEndpoint(useChinaPlatform), GetPlatformRefreshTokenCredential(useChinaPlatform)); // Upload snapshots. var simDeploymentSnapshotId = UploadSnapshot(snapshotServiceClient, simDeploymentSnapshotPath, projectName, simDeploymentName, useChinaPlatform); if (simDeploymentSnapshotId.Length == 0) { throw new Exception("Error while uploading sim player snapshot."); } var playerAuthServiceClient = PlayerAuthServiceClient.Create(GetApiEndpoint(useChinaPlatform), GetPlatformRefreshTokenCredential(useChinaPlatform)); // Create development authentication token used by the simulated players. var dat = playerAuthServiceClient.CreateDevelopmentAuthenticationToken( new CreateDevelopmentAuthenticationTokenRequest { Description = "DAT for simulated player deployment.", Lifetime = Duration.FromTimeSpan(new TimeSpan(7, 0, 0, 0)), ProjectName = projectName }); // Add worker flags to sim deployment JSON. var devAuthTokenFlag = new JObject(); devAuthTokenFlag.Add("name", "simulated_players_dev_auth_token"); devAuthTokenFlag.Add("value", dat.TokenSecret); var targetDeploymentFlag = new JObject(); targetDeploymentFlag.Add("name", "simulated_players_target_deployment"); targetDeploymentFlag.Add("value", mainDeploymentName); var numSimulatedPlayersFlag = new JObject(); numSimulatedPlayersFlag.Add("name", "total_num_simulated_players"); numSimulatedPlayersFlag.Add("value", $"{numSimPlayers}"); var simDeploymentConfigJson = File.ReadAllText(simDeploymentJsonPath); dynamic simDeploymentConfig = JObject.Parse(simDeploymentConfigJson); if (simDeploymentJsonPath.EndsWith(".pb.json")) { for (var i = 0; i < simDeploymentConfig.worker_flagz.Count; ++i) { if (simDeploymentConfig.worker_flagz[i].worker_type == CoordinatorWorkerName) { simDeploymentConfig.worker_flagz[i].flagz.Add(devAuthTokenFlag); simDeploymentConfig.worker_flagz[i].flagz.Add(targetDeploymentFlag); simDeploymentConfig.worker_flagz[i].flagz.Add(numSimulatedPlayersFlag); break; } } for (var i = 0; i < simDeploymentConfig.flagz.Count; ++i) { if (simDeploymentConfig.flagz[i].name == "loadbalancer_v2_config_json") { string layerConfigJson = simDeploymentConfig.flagz[i].value; dynamic loadBalanceConfig = JObject.Parse(layerConfigJson); var lbLayerConfigurations = loadBalanceConfig.layerConfigurations; for (var j = 0; j < lbLayerConfigurations.Count; ++j) { if (lbLayerConfigurations[j].layer == CoordinatorWorkerName) { var rectangleGrid = lbLayerConfigurations[j].rectangleGrid; rectangleGrid.cols = numSimPlayers; rectangleGrid.rows = 1; break; } } simDeploymentConfig.flagz[i].value = Newtonsoft.Json.JsonConvert.SerializeObject(loadBalanceConfig); break; } } } else // regular non pb.json { for (var i = 0; i < simDeploymentConfig.workers.Count; ++i) { if (simDeploymentConfig.workers[i].worker_type == CoordinatorWorkerName) { simDeploymentConfig.workers[i].flags.Add(devAuthTokenFlag); simDeploymentConfig.workers[i].flags.Add(targetDeploymentFlag); simDeploymentConfig.workers[i].flags.Add(numSimulatedPlayersFlag); } } // Specify the number of managed coordinator workers to start by editing // the load balancing options in the launch config. It creates a rectangular // launch config of N cols X 1 row, N being the number of coordinators // to create. // This assumes the launch config contains a rectangular load balancing // layer configuration already for the coordinator worker. var lbLayerConfigurations = simDeploymentConfig.load_balancing.layer_configurations; for (var i = 0; i < lbLayerConfigurations.Count; ++i) { if (lbLayerConfigurations[i].layer == CoordinatorWorkerName) { var rectangleGrid = lbLayerConfigurations[i].rectangle_grid; rectangleGrid.cols = numSimPlayers; rectangleGrid.rows = 1; } } } // Create simulated player deployment. var simDeployment = new Deployment { AssemblyId = assemblyName, LaunchConfig = new LaunchConfig { ConfigJson = simDeploymentConfig.ToString() }, Name = simDeploymentName, ProjectName = projectName, RuntimeVersion = runtimeVersion, StartingSnapshotId = simDeploymentSnapshotId, }; if (!String.IsNullOrEmpty(clusterCode)) { simDeployment.ClusterCode = clusterCode; } else { simDeployment.RegionCode = regionCode; } simDeployment.Tag.Add(DEPLOYMENT_LAUNCHED_BY_LAUNCHER_TAG); simDeployment.Tag.Add(SIM_PLAYER_DEPLOYMENT_TAG); Console.WriteLine( $"Creating the simulated player deployment {simDeploymentName} in project {projectName} with {numSimPlayers} simulated players. Link: https://console.improbable.io/projects/{projectName}/deployments/{simDeploymentName}/overview"); var simDeploymentCreateOp = deploymentServiceClient.CreateDeployment(new CreateDeploymentRequest { Deployment = simDeployment }); return(simDeploymentCreateOp); }
public static void Main(string[] args) { // See https://support.microsoft.com/en-gb/help/821268/contention-poor-performance-and-deadlocks-when-you-make-calls-to-web-s // Experimentation shows we need the ThreadPool to always spin up threads for good performance under load ThreadPool.GetMaxThreads(out var workerThreads, out var ioThreads); ThreadPool.SetMinThreads(workerThreads, ioThreads); Parser.Default.ParseArguments <PartyServerCommandLineArgs>(args) .WithParsed(parsedArgs => { parsedArgs.Validate(); var spatialRefreshToken = Secrets.GetEnvSecret(SpatialRefreshTokenEnvironmentVariable); PartyDataModel.Defaults.MinMembers = (uint)parsedArgs.DefaultMinMembers; PartyDataModel.Defaults.MaxMembers = (uint)parsedArgs.DefaultMaxMembers; Log.Logger = new LoggerConfiguration() .WriteTo.Console(new RenderedCompactJsonFormatter()) .Enrich.FromLogContext() .CreateLogger(); IAnalyticsSender analyticsSender = new AnalyticsSenderBuilder("gateway_party") .WithCommandLineArgs(parsedArgs) .With(new LogExceptionStrategy(Log.Logger)) .Build(); using (var server = GrpcBaseServer.Build(parsedArgs)) using (var memoryStoreManager = new RedisClientManager(parsedArgs.RedisConnectionString)) { Log.Information($"Successfully connected to Redis at {parsedArgs.RedisConnectionString}"); server.AddInterceptor(new PlayerIdentityTokenValidatingInterceptor( PlayerAuthServiceClient.Create(/*put my auth server address here*/ credentials: new PlatformRefreshTokenCredential(spatialRefreshToken)), memoryStoreManager.GetRawClient(Database.CACHE) )) .AddInterceptor(new ExceptionMappingInterceptor(new Dictionary <Type, StatusCode> { { typeof(EntryNotFoundException), StatusCode.NotFound }, { typeof(EntryAlreadyExistsException), StatusCode.AlreadyExists }, { typeof(TransactionAbortedException), StatusCode.Unavailable } })); server.AddService( PartyService.BindService(new PartyServiceImpl(memoryStoreManager, analyticsSender))); server.AddService( InviteService.BindService(new InviteServiceImpl(memoryStoreManager, analyticsSender))); var serverTask = Task.Run(() => server.Start()); var signalTask = Task.Run(() => UnixSignal.WaitAny(new[] { new UnixSignal(Signum.SIGINT), new UnixSignal(Signum.SIGTERM) })); Task.WaitAny(serverTask, signalTask); if (signalTask.IsCompleted) { Log.Information($"Received UNIX signal {signalTask.Result}"); Log.Information("Server shutting down..."); server.Shutdown(); serverTask.Wait(); Log.Information("Server stopped cleanly"); } else { /* The server task has completed; we can just exit. */ Log.Information("The Party server has stopped itself or encountered an unhandled exception."); } } }); }
private static Operation <Deployment, CreateDeploymentMetadata> CreateSimPlayerDeploymentAsync(DeploymentServiceClient deploymentServiceClient, string projectName, string assemblyName, string mainDeploymentName, string simDeploymentName, string simDeploymentJsonPath, string regionCode, int simNumPlayers) { var playerAuthServiceClient = PlayerAuthServiceClient.Create(); // Create development authentication token used by the simulated players. var dat = playerAuthServiceClient.CreateDevelopmentAuthenticationToken( new CreateDevelopmentAuthenticationTokenRequest { Description = "DAT for simulated player deployment.", Lifetime = Duration.FromTimeSpan(new TimeSpan(7, 0, 0, 0)), ProjectName = projectName }); // Add worker flags to sim deployment JSON. var devAuthTokenFlag = new JObject(); devAuthTokenFlag.Add("name", "simulated_players_dev_auth_token"); devAuthTokenFlag.Add("value", dat.TokenSecret); var targetDeploymentFlag = new JObject(); targetDeploymentFlag.Add("name", "simulated_players_target_deployment"); targetDeploymentFlag.Add("value", mainDeploymentName); var numSimulatedPlayersFlag = new JObject(); numSimulatedPlayersFlag.Add("name", "total_num_simulated_players"); numSimulatedPlayersFlag.Add("value", $"{simNumPlayers}"); var simWorkerConfigJson = File.ReadAllText(simDeploymentJsonPath); dynamic simWorkerConfig = JObject.Parse(simWorkerConfigJson); for (var i = 0; i < simWorkerConfig.workers.Count; ++i) { if (simWorkerConfig.workers[i].worker_type == CoordinatorWorkerName) { simWorkerConfig.workers[i].flags.Add(devAuthTokenFlag); simWorkerConfig.workers[i].flags.Add(targetDeploymentFlag); simWorkerConfig.workers[i].flags.Add(numSimulatedPlayersFlag); } } // Specify the number of managed coordinator workers to start by editing // the load balancing options in the launch config. It creates a rectangular // launch config of N cols X 1 row, N being the number of coordinators // to create. // This assumes the launch config contains a rectangular load balancing // layer configuration already for the coordinator worker. var lbLayerConfigurations = simWorkerConfig.load_balancing.layer_configurations; for (var i = 0; i < lbLayerConfigurations.Count; ++i) { if (lbLayerConfigurations[i].layer == CoordinatorWorkerName) { var rectangleGrid = lbLayerConfigurations[i].rectangle_grid; rectangleGrid.cols = simNumPlayers; rectangleGrid.rows = 1; } } simWorkerConfigJson = simWorkerConfig.ToString(); // Create simulated player deployment. var simDeploymentConfig = new Deployment { AssemblyId = assemblyName, LaunchConfig = new LaunchConfig { ConfigJson = simWorkerConfigJson }, Name = simDeploymentName, ProjectName = projectName, RegionCode = regionCode // No snapshot included for the simulated player deployment }; simDeploymentConfig.Tag.Add(DEPLOYMENT_LAUNCHED_BY_LAUNCHER_TAG); simDeploymentConfig.Tag.Add(SIM_PLAYER_DEPLOYMENT_TAG); Console.WriteLine( $"Creating the simulated player deployment {simDeploymentName} in project {projectName} with {simNumPlayers} simulated players. Link: https://console.improbable.io/projects/{projectName}/deployments/{simDeploymentName}/overview"); var simDeploymentCreateOp = deploymentServiceClient.CreateDeployment(new CreateDeploymentRequest { Deployment = simDeploymentConfig }); return(simDeploymentCreateOp); }
public static void Init(string token) { var credentials = new PlatformRefreshTokenCredential(token); PlayerAuthServiceClient = PlayerAuthServiceClient.Create(credentials: credentials); }