Exemple #1
0
        private static int StopDeployment(string[] args)
        {
            var projectName  = args[1];
            var deploymentId = args[2];

            var deploymentServiceClient = DeploymentServiceClient.Create();

            try
            {
                deploymentServiceClient.StopDeployment(new StopDeploymentRequest
                {
                    Id          = deploymentId,
                    ProjectName = projectName
                });
            }
            catch (Grpc.Core.RpcException e)
            {
                if (e.Status.StatusCode == Grpc.Core.StatusCode.NotFound)
                {
                    Console.WriteLine("<error:unknown-deployment>");
                }
                else
                {
                    throw;
                }
            }

            return(0);
        }
        public static void Init(string serviceAccountToken)
        {
            var credentials = new PlatformRefreshTokenCredential(serviceAccountToken);

            deploymentServiceClient = DeploymentServiceClient.Create(credentials: credentials);
            snapshotServiceClient   = SnapshotServiceClient.Create(credentials: credentials);
        }
Exemple #3
0
        public async Task <object> CloneDeployment(dynamic data)
        {
            return(await Task.Run(() => {
                PlatformRefreshTokenCredential CredentialWithProvidedToken = new PlatformRefreshTokenCredential(data._RefreshToken);
                DeploymentServiceClient _deploymentServiceClient = DeploymentServiceClient.Create(credentials: CredentialWithProvidedToken);
                var suitableDeployment = _deploymentServiceClient.ListDeployments(new ListDeploymentsRequest
                {
                    ProjectName = data._ProjectName
                }).First(d => d.Id.Contains(data._DeploymentID));

                var newDeployment = suitableDeployment.Clone();
                newDeployment.StartingSnapshotId = data._SnapshotID;
                newDeployment.Tag.Clear();
                newDeployment = _deploymentServiceClient.CreateDeployment(new CreateDeploymentRequest {
                    Deployment = newDeployment
                })
                                .PollUntilCompleted()
                                .GetResultOrNull();
                newDeployment.Tag.Add(data._ScenarioDeploymentTag);
                _deploymentServiceClient.UpdateDeployment(new UpdateDeploymentRequest {
                    Deployment = newDeployment
                });
                return newDeployment.Id;
            }));
        }
Exemple #4
0
        static void Main(string[] args)
        {
            Log.Logger = new LoggerConfiguration()
                         .WriteTo.Console(new RenderedCompactJsonFormatter())
                         .Enrich.FromLogContext()
                         .CreateLogger();

            // See https://support.microsoft.com/en-gb/help/821268/contention-poor-performance-and-deadlocks-when-you-make-calls-to-web-s
            ThreadPool.SetMaxThreads(100, 100);
            ThreadPool.SetMinThreads(50, 50);

            Parser.Default.ParseArguments <DeploymentPoolArgs>(args)
            .WithParsed(parsedArgs =>
            {
                parsedArgs.Validate();
                var spatialRefreshToken = Environment.GetEnvironmentVariable(SpatialRefreshTokenEnvironmentVariable) ??
                                          throw new Exception(
                    $"{SpatialRefreshTokenEnvironmentVariable} environment variable is required.");
                if (spatialRefreshToken == "")
                {
                    throw new ArgumentException("Refresh token should not be empty");
                }

                IAnalyticsSender analyticsSender = new AnalyticsSenderBuilder("deployment_pool")
                                                   .WithCommandLineArgs(parsedArgs)
                                                   .With(new LogExceptionStrategy(Log.Logger))
                                                   .Build();

                var spatialDeploymentClient =
                    DeploymentServiceClient.Create(credentials: new PlatformRefreshTokenCredential(spatialRefreshToken));
                var spatialSnapshotClient =
                    SnapshotServiceClient.Create(credentials: new PlatformRefreshTokenCredential(spatialRefreshToken));
                var platformInvoker = new PlatformInvoker(parsedArgs, spatialDeploymentClient, spatialSnapshotClient, analyticsSender);


                var cancelTokenSource = new CancellationTokenSource();
                var cancelToken       = cancelTokenSource.Token;

                var metricsServer  = new MetricServer(parsedArgs.MetricsPort).Start();
                var dplPool        = new DeploymentPool(parsedArgs, spatialDeploymentClient, platformInvoker, cancelToken, analyticsSender);
                var dplPoolTask    = Task.Run(() => dplPool.Start());
                var unixSignalTask = Task.Run(() => UnixSignal.WaitAny(new[] { new UnixSignal(Signum.SIGINT), new UnixSignal(Signum.SIGTERM) }));
                Task.WaitAny(dplPoolTask, unixSignalTask);

                if (unixSignalTask.IsCompleted)
                {
                    Log.Information($"Received UNIX signal {unixSignalTask.Result}");
                    Log.Information("Server shutting down...");
                    cancelTokenSource.Cancel();
                    metricsServer.StopAsync();
                    dplPoolTask.Wait();
                    Log.Information("Server stopped cleanly");
                }
                else
                {
                    /* The server task has completed; we can just exit. */
                    Log.Information($"The deployment pool has stopped itself or encountered an unhandled exception {dplPoolTask.Exception}");
                }
            });
        }
Exemple #5
0
        private static int ListDeployments(string[] args)
        {
            var projectName = args[1];
            var regionCode  = args[2];

            var deploymentServiceClient = DeploymentServiceClient.Create(GetApiEndpoint(regionCode), GetPlatformRefreshTokenCredential(regionCode));
            var activeDeployments       = ListLaunchedActiveDeployments(deploymentServiceClient, projectName);

            foreach (var deployment in activeDeployments)
            {
                var status          = deployment.Status;
                var overviewPageUrl = $"https://console.improbable.io/projects/{projectName}/deployments/{deployment.Name}/overview/{deployment.Id}";

                if (deployment.Tag.Contains(SIM_PLAYER_DEPLOYMENT_TAG))
                {
                    Console.WriteLine($"<simulated-player-deployment> {deployment.Id} {deployment.Name} {deployment.RegionCode} {overviewPageUrl} {status}");
                }
                else
                {
                    Console.WriteLine($"<deployment> {deployment.Id} {deployment.Name} {deployment.RegionCode} {overviewPageUrl} {status}");
                }
            }

            return(0);
        }
Exemple #6
0
        public static int StopDeployment(Options.Stop options)
        {
            var deploymentServiceClient = DeploymentServiceClient.Create();

            try
            {
                deploymentServiceClient.StopDeployment(new StopDeploymentRequest
                {
                    Id          = options.DeploymentId,
                    ProjectName = options.ProjectName
                });
            }
            catch (Grpc.Core.RpcException e)
            {
                if (e.Status.StatusCode == Grpc.Core.StatusCode.NotFound)
                {
                    Ipc.WriteError(Ipc.ErrorCode.NotFound,
                                   $"Could not find deployment with ID {options.DeploymentId} in project {options.ProjectName}");
                    return(Program.ErrorExitCode);
                }

                throw;
            }

            return(Program.SuccessExitCode);
        }
Exemple #7
0
        private static int StopDeployments(string[] args)
        {
            var projectName = args[1];
            var regionCode  = args[2];

            var deploymentServiceClient = DeploymentServiceClient.Create(GetApiEndpoint(regionCode), GetPlatformRefreshTokenCredential(regionCode));

            if (args.Length == 4)
            {
                // Stop only the specified deployment.
                var deploymentId = args[3];
                StopDeploymentById(deploymentServiceClient, projectName, deploymentId);

                return(0);
            }

            // Stop all active deployments launched by this launcher.
            var activeDeployments = ListLaunchedActiveDeployments(deploymentServiceClient, projectName);

            foreach (var deployment in activeDeployments)
            {
                var deploymentId = deployment.Id;
                StopDeploymentById(deploymentServiceClient, projectName, deploymentId);
            }

            return(0);
        }
Exemple #8
0
        private static int StopDeployments(string[] args)
        {
            var projectName = args[1];

            var deploymentServiceClient = DeploymentServiceClient.Create();

            if (args.Length == 3)
            {
                // Stop only the specified deployment.
                var deploymentId = args[2];
                StopDeploymentById(deploymentServiceClient, projectName, deploymentId);

                return(0);
            }

            // Stop all active deployments launched by this launcher.
            var activeDeployments = ListLaunchedActiveDeployments(deploymentServiceClient, projectName);

            foreach (var deployment in activeDeployments)
            {
                var deploymentId = deployment.Id;
                StopDeploymentById(deploymentServiceClient, projectName, deploymentId);
            }

            return(0);
        }
 public static DeploymentServiceClient CreateDeploymentClient(Options.Common options)
 {
     return(string.IsNullOrEmpty(options.Environment)
         ? DeploymentServiceClient.Create()
         : DeploymentServiceClient.Create(GetEndpoint(options.Environment),
                                          GetTokenCredential(options.Environment)));
 }
Exemple #10
0
        private static int CreateSimDeployments(string[] args, bool useChinaPlatform)
        {
            var projectName               = args[1];
            var assemblyName              = args[2];
            var runtimeVersion            = args[3];
            var targetDeploymentName      = args[4];
            var simDeploymentName         = args[5];
            var simDeploymentJson         = args[6];
            var simDeploymentRegion       = args[7];
            var simDeploymentCluster      = args[8];
            var simDeploymentSnapshotPath = args[9];

            var simNumPlayers = 0;

            if (!Int32.TryParse(args[10], out simNumPlayers))
            {
                Console.WriteLine("Cannot parse the number of simulated players to connect.");
                return(1);
            }

            try
            {
                var deploymentServiceClient = DeploymentServiceClient.Create(GetApiEndpoint(useChinaPlatform));

                if (DeploymentExists(deploymentServiceClient, projectName, simDeploymentName))
                {
                    StopDeploymentByName(deploymentServiceClient, projectName, simDeploymentName);
                }

                var createSimDeploymentOp = CreateSimPlayerDeploymentAsync(deploymentServiceClient,
                                                                           projectName, assemblyName, runtimeVersion, targetDeploymentName, simDeploymentName,
                                                                           simDeploymentJson, simDeploymentSnapshotPath, simDeploymentRegion, simDeploymentCluster, simNumPlayers, useChinaPlatform);

                // Wait for both deployments to be created.
                Console.WriteLine("Waiting for the simulated player deployment to be ready...");
                var simPlayerDeployment = createSimDeploymentOp.PollUntilCompleted().GetResultOrNull();
                if (simPlayerDeployment == null)
                {
                    Console.WriteLine("Failed to create the simulated player deployment");
                    return(1);
                }

                Console.WriteLine("Done! Simulated players will start to connect to your deployment");
            }
            catch (Grpc.Core.RpcException e)
            {
                if (e.Status.StatusCode == Grpc.Core.StatusCode.NotFound)
                {
                    Console.WriteLine(
                        $"Unable to launch the deployment(s). This is likely because the project '{projectName}' or assembly '{assemblyName}' doesn't exist.");
                }
                else
                {
                    throw;
                }
            }

            return(0);
        }
        private static int StopDeployments(string[] args, bool useChinaPlatform)
        {
            var projectName = args[1];

            var deploymentServiceClient = DeploymentServiceClient.Create(GetApiEndpoint(useChinaPlatform), GetPlatformRefreshTokenCredential(useChinaPlatform));

            var deploymentIdsToStop = new List <string>();

            if (args.Length == 3)
            {
                // Stop only the specified deployment.
                var deploymentId = args[2];
                deploymentIdsToStop.Add(deploymentId);
            }
            else
            {
                // Stop all active deployments launched by this launcher.
                var activeDeployments = ListLaunchedActiveDeployments(deploymentServiceClient, projectName);
                foreach (var deployment in activeDeployments)
                {
                    deploymentIdsToStop.Add(deployment.Id);
                }
            }

            var deploymentIdsToTasks = new Dictionary <string, Task>();
            var erroredDeploymentIds = new List <string>();

            Console.WriteLine($"Will stop {deploymentIdsToStop.Count()} deployment(s)");
            foreach (var deploymentId in deploymentIdsToStop)
            {
                deploymentIdsToTasks.Add(deploymentId, StopDeploymentByIdAsync(deploymentServiceClient, projectName, deploymentId));
            }
            ;

            try
            {
                Task.WaitAll(deploymentIdsToTasks.Values.ToArray());
            }
            catch
            {
                // Retrieve individual exceptions from AggregateException thrown by Task.WaitAll
                var throwers = deploymentIdsToTasks.Where(task => task.Value.Exception != null);
                foreach (KeyValuePair <string, Task> erroredTask in throwers)
                {
                    Exception inner = erroredTask.Value.Exception.InnerException;

                    string erroredDeploymentId = erroredTask.Key;
                    erroredDeploymentIds.Add(erroredDeploymentId);
                    Console.WriteLine($"Error while stopping deployment {erroredDeploymentId}: {inner.Message}");
                }
            }

            Console.WriteLine($"Deployment(s) stopped with {erroredDeploymentIds.Count()} errors");
            return(0);
        }
Exemple #12
0
        public SpatialOSPlatformService()
        {
            var spatialOSServiceAccountToken = Environment.GetEnvironmentVariable("SPATIALOS_TOKEN");

            DeploymentTagFilter = Environment.GetEnvironmentVariable("DEPLOYMENT_TAG");

            var credentialsWithProvidedToken = new PlatformRefreshTokenCredential(spatialOSServiceAccountToken);

            deploymentServiceClient = DeploymentServiceClient.Create(credentials: credentialsWithProvidedToken);
            playerAuthServiceClient = PlayerAuthServiceClient.Create(credentials: credentialsWithProvidedToken);
        }
Exemple #13
0
 public async Task <object> StopDeployment(dynamic data)
 {
     return(await Task.Run(() => {
         PlatformRefreshTokenCredential CredentialWithProvidedToken = new PlatformRefreshTokenCredential(data._RefreshToken);
         DeploymentServiceClient _deploymentServiceClient = DeploymentServiceClient.Create(credentials: CredentialWithProvidedToken);
         _deploymentServiceClient.StopDeployment(new StopDeploymentRequest
         {
             Id = data._DeploymentID,
             ProjectName = data._ProjectName
         });
         return data._DeploymentID;
     }));
 }
Exemple #14
0
        public static int ListDeployments(Options.List options)
        {
            var deploymentServiceClient = DeploymentServiceClient.Create();
            var listDeploymentsResult   = deploymentServiceClient.ListDeployments(new ListDeploymentsRequest
            {
                ProjectName = options.ProjectName
            });

            Ipc.WriteDeploymentInfo(listDeploymentsResult.Where(deployment =>
                                                                deployment.Status == Deployment.Types.Status.Running));

            return(Program.SuccessExitCode);
        }
Exemple #15
0
        public async Task <object> GetDeploymentIDByTag(dynamic data)
        {
            return(await Task.Run(() => {
                PlatformRefreshTokenCredential CredentialWithProvidedToken = new PlatformRefreshTokenCredential(data._RefreshToken);
                DeploymentServiceClient _deploymentServiceClient = DeploymentServiceClient.Create(credentials: CredentialWithProvidedToken);
                var suitableDeployment = _deploymentServiceClient.ListDeployments(new ListDeploymentsRequest
                {
                    ProjectName = data._ProjectName,
                    DeploymentName = data._DeploymentName
                }).First(d => d.Tag.Contains(data._ScenarioDeploymentTag));

                return suitableDeployment.Id;
            }));
        }
Exemple #16
0
        protected Matcher()
        {
            var spatialRefreshToken = Environment.GetEnvironmentVariable(SpatialRefreshTokenEnvironmentVariable) ??
                                      throw new Exception(
                                                $"{SpatialRefreshTokenEnvironmentVariable} environment variable is required.");

            _spatialDeploymentClient =
                DeploymentServiceClient.Create(credentials: new PlatformRefreshTokenCredential(spatialRefreshToken));
            _gatewayClient =
                new GatewayInternalService.GatewayInternalServiceClient(new Channel(
                                                                            Environment.GetEnvironmentVariable(GatewayServiceTargetEnvironmentVariable)
                                                                            ?? throw new Exception(
                                                                                $"Environment variable {GatewayServiceTargetEnvironmentVariable} is required."),
                                                                            ChannelCredentials.Insecure));
        }
Exemple #17
0
        private static int ListDeployments(string[] args)
        {
            var projectName = args[1];

            var deploymentServiceClient = DeploymentServiceClient.Create();
            var listDeploymentsResult   = deploymentServiceClient.ListDeployments(new ListDeploymentsRequest
            {
                ProjectName = projectName
            });

            foreach (var deployment in listDeploymentsResult)
            {
                if (deployment.Status == Deployment.Types.Status.Running)
                {
                    Console.WriteLine($"<deployment> {deployment.Id} {deployment.Name}");
                }
            }

            return(0);
        }
Exemple #18
0
        public async Task <object> ChangeDeploymentCapacity(dynamic data)
        {
            return(await Task.Run(() => {
                PlatformRefreshTokenCredential CredentialWithProvidedToken = new PlatformRefreshTokenCredential(data._RefreshToken);
                DeploymentServiceClient _deploymentServiceClient = DeploymentServiceClient.Create(credentials: CredentialWithProvidedToken);
                var suitableDeployment = _deploymentServiceClient.ListDeployments(new ListDeploymentsRequest
                {
                    ProjectName = data._ProjectName
                }).First(d => d.Id.Contains(data._DeploymentID));

                suitableDeployment.WorkerConnectionCapacities.Clear();
                suitableDeployment.WorkerConnectionCapacities.Add(new WorkerCapacity
                {
                    WorkerType = data._ScenarioWorkerType,
                    MaxCapacity = data._DeploymentCapacity
                });
                _deploymentServiceClient.UpdateDeployment(new UpdateDeploymentRequest {
                    Deployment = suitableDeployment
                });
                return suitableDeployment.Id;
            }));
        }
Exemple #19
0
 public async Task <object> CreateDeployment(dynamic data)
 {
     return(await Task.Run(() => {
         PlatformRefreshTokenCredential CredentialWithProvidedToken = new PlatformRefreshTokenCredential(data._RefreshToken);
         DeploymentServiceClient _deploymentServiceClient = DeploymentServiceClient.Create(credentials: CredentialWithProvidedToken);
         var newDeployment = _deploymentServiceClient.CreateDeployment(new CreateDeploymentRequest
         {
             Deployment = new Deployment
             {
                 ProjectName = data._ProjectName,
                 Name = data._DeploymentName,
                 LaunchConfig = new LaunchConfig
                 {
                     ConfigJson = data._Config
                 },
                 AssemblyId = data._AssemblyID,
                 Tag = { data._ScenarioDeploymentTag }
             }
         }).PollUntilCompleted().GetResultOrNull();
         return newDeployment.Id;
     }));
 }
Exemple #20
0
 public async Task <object> SetDeploymentMaintenance(dynamic data)
 {
     return(await Task.Run(() => {
         PlatformRefreshTokenCredential CredentialWithProvidedToken = new PlatformRefreshTokenCredential(data._RefreshToken);
         DeploymentServiceClient _deploymentServiceClient = DeploymentServiceClient.Create(credentials: CredentialWithProvidedToken);
         var suitableDeployment = _deploymentServiceClient.ListDeployments(new ListDeploymentsRequest
         {
             ProjectName = data._ProjectName,
             DeploymentName = data._DeploymentName
         }).First(d => d.Id.Contains(data._DeploymentID));
         suitableDeployment.Tag.Remove(data._ScenarioDeploymentTag);
         suitableDeployment.WorkerFlags.Add(new WorkerFlag
         {
             Key = "maintenance",
             Value = "true",
             WorkerType = data._ScenarioWorkerType
         });
         _deploymentServiceClient.UpdateDeployment(new UpdateDeploymentRequest {
             Deployment = suitableDeployment
         });
         return suitableDeployment.Id;
     }));
 }
Exemple #21
0
        public static async Task Main(string[] args)
        {
            if (args.Length != 3)
            {
                throw new ArgumentException("Expected usage: SpotShim.exe <deployment_id> <deployment_name> <project_name>");
            }

            var localApiEndpoint        = new PlatformApiEndpoint("localhost", SpatialdPort, insecure: true);
            var deploymentServiceClient = DeploymentServiceClient.Create(localApiEndpoint);

            var request = new UpdateDeploymentRequest
            {
                Deployment = new Deployment
                {
                    Id          = args[0],
                    Name        = args[1],
                    ProjectName = args[2],
                    Tag         = { "dev_login" }
                }
            };

            await deploymentServiceClient.UpdateDeploymentAsync(request);
        }
        public static async Task StopLocalAsync(ProjectConfig config, CancellationToken cancellation = default, IProgress <string>?progress = null)
        {
            var client = DeploymentServiceClient.Create(GetLocalApiChannel());

            var deployments = await client.ListDeploymentsAsync(new ListDeploymentsRequest
            {
                DeploymentName = "local",
                ProjectName    = config.ProjectName,
                DeploymentStoppedStatusFilter = ListDeploymentsRequest.Types.DeploymentStoppedStatusFilter.NotStoppedDeployments
            }, CallSettings.FromCancellationToken(cancellation)).ReadPageAsync(50, cancellation);

            var tasks = new List <Task>();

            foreach (var dpl in deployments)
            {
                progress?.Report($"Stopping {dpl.Id}...");
                tasks.Add(client.DeleteDeploymentAsync(new DeleteDeploymentRequest {
                    Id = dpl.Id
                }, CallSettings.FromCancellationToken(cancellation)));
            }

            Task.WaitAll(tasks.ToArray(), cancellation);
        }
Exemple #23
0
    static void Run(CommandLineOptions options)
    {
        Console.WriteLine("Starting DeploymentServiceClient");
        DeploymentServiceClient = DeploymentServiceClient.Create();
        //Check if the deployment exists before waiting to get logs.
        var request = new GetRunningDeploymentByNameRequest()
        {
            DeploymentName = options.Deployment,
            ProjectName    = options.Project,
            View           = ViewType.Full
        };

        Console.WriteLine("Requesting deployment by name {0}", options.Deployment);
        var deploy = DeploymentServiceClient.GetRunningDeploymentByName(request);

        if (deploy == null)
        {
            Console.WriteLine("Requested deployment {0} does not exist in project {1}. Exiting.", options.Deployment, options.Project);
            return;
        }

        Console.WriteLine("Found deployment");
        {
            var testingFlag = new WorkerFlag()
            {
                Key        = "ExtendedTesting",
                Value      = "True",
                WorkerType = "UnrealWorker"
            };

            var flags = deploy.Deployment.WorkerFlags.Clone();

            flags.Add(testingFlag);

            DeploymentServiceClient.SetDeploymentWorkerFlags(new SetDeploymentWorkerFlagsRequest()
            {
                DeploymentId = deploy.Deployment.Id,
                WorkerFlags  = { flags }
            });
        }
        Console.WriteLine("Worker flag set, sleeping for {0} minutes", options.Delay);
        //Sleep for {delay} minutes.
        Thread.Sleep((int)(1000f * 60f * options.Delay));

        //Set testing flag to false
        {
            var testingFlag = new WorkerFlag()
            {
                Key        = "ExtendedTesting",
                Value      = "False",
                WorkerType = "UnrealWorker"
            };

            var flags = deploy.Deployment.WorkerFlags.Clone();
            flags.Remove(flags.FirstOrDefault(a => a.Key == "ExtendedTesting"));
            flags.Add(testingFlag);

            DeploymentServiceClient.SetDeploymentWorkerFlags(new SetDeploymentWorkerFlagsRequest()
            {
                DeploymentId = deploy.Deployment.Id,
                WorkerFlags  = { flags }
            });
        }
        //Wait one minute to allow server processes to print outcomes to the log after testing is stopped.
        Thread.Sleep(60 * 1000);

        //Get log
        var authValue = PlatformRefreshTokenCredential.AutoDetected.Token.AccessToken;

        using var wc = new WebClient();
        wc.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + authValue);
        List <string> log = null;

        #region AttemptDownloads
        try
        {
            log = wc.DownloadString(string.Format(WorkerLogPath, options.Project, options.Deployment, SimPathA)).Split('\n').ToList();
        }
        catch (WebException e)
        {
            if (e.Response.ToString().Contains("404"))
            {
                Console.WriteLine("Log file was not found on " + SimPathA);
            }
            else if (e.Response.ToString().Contains("401"))
            {
                Console.WriteLine(
                    "Unauthorized to access resource, check your refresh token and permission to access deployments in " +
                    options.Project);
                return;
            }
        }

        if (log == null)
        {
            try
            {
                log = wc.DownloadString(string.Format(WorkerLogPath, options.Project, options.Deployment, SimPathB)).Split('\n').ToList();
            }
            catch (WebException e)
            {
                if (e.Response.ToString().Contains("404"))
                {
                    Console.WriteLine("Log file was not found on " + SimPathB);
                }
                else if (e.Response.ToString().Contains("401"))
                {
                    Console.WriteLine(e.ToString());
                    return;
                }
            }
        }

        if (log == null)
        {
            try
            {
                log = wc.DownloadString(string.Format(WorkerLogPath, options.Project, options.Deployment, SimPathC)).Split('\n').ToList();
            }
            catch (WebException e)
            {
                if (e.Response.ToString().Contains("404"))
                {
                    Console.WriteLine("Log file was not found on " + SimPathC);
                }
                else if (e.Response.ToString().Contains("401"))
                {
                    Console.WriteLine(e.ToString());
                    return;
                }
            }
        }

        if (log == null)
        {
            try
            {
                log = wc.DownloadString(string.Format(WorkerLogPath, options.Project, options.Deployment, SimPathD)).Split('\n').ToList();
            }
            catch (WebException e)
            {
                if (e.Response.ToString().Contains("404"))
                {
                    Console.WriteLine("Log file was not found on " + SimPathD);
                }
                else if (e.Response.ToString().Contains("401"))
                {
                    Console.WriteLine(e.ToString());
                    return;
                }
            }
        }

        if (log == null)
        {
            Console.WriteLine("Raw worker log could not be found - Exiting.");
            return;
        }
        #endregion

        Dictionary <string, int> logEntries = new Dictionary <string, int>();
        //Build a dictionary so we can count the errors/warnings that are identical and present a nicer output, print them anyway in case we'd like to see them in order.
        foreach (var line in log)
        {
            if (line.ToLower().Contains("warning"))
            {
                Console.WriteLine("WARNING: " + line);
                var trimmedLine = line.Substring(line.IndexOf(']') + 1);
                if (logEntries.ContainsKey("WARNING: " + trimmedLine))
                {
                    logEntries["WARNING: " + trimmedLine]++;
                }
                else
                {
                    logEntries.Add("WARNING: " + trimmedLine, 1);
                }
            }

            if (line.ToLower().Contains("error"))
            {
                Console.WriteLine("ERROR: " + line);
                var trimmedLine = line.Substring(line.IndexOf(']') + 1);
                if (logEntries.ContainsKey("ERROR: " + trimmedLine))
                {
                    logEntries["ERROR: " + trimmedLine]++;
                }
                else
                {
                    logEntries.Add("ERROR: " + trimmedLine, 1);
                }
            }
        }

        Console.WriteLine("+++ Clean Error/Warning Output");
StartPrint:
        if (logEntries.Count > 0)
        {
            var entry = logEntries.ElementAt(0);
            logEntries.Remove(entry.Key);
            Console.WriteLine("( {0} ) {1}", entry.Value, entry.Key);
            goto StartPrint;
        }
    }
        private static int CreateDeployment(string[] args, bool useChinaPlatform)
        {
            // Argument count can vary because of optional arguments
            bool launchSimPlayerDeployment = args.Length == 16 || args.Length == 15;

            var projectName                = args[1];
            var assemblyName               = args[2];
            var runtimeVersion             = args[3];
            var mainDeploymentName         = args[4];
            var mainDeploymentJsonPath     = args[5];
            var mainDeploymentSnapshotPath = args[6];
            var mainDeploymentRegion       = args[7];
            var mainDeploymentCluster      = args[8];
            var mainDeploymentTags         = args[9];

            var simDeploymentBaseName   = string.Empty;
            var simDeploymentJson       = string.Empty;
            var simDeploymentRegion     = string.Empty;
            var simDeploymentCluster    = string.Empty;
            var numSimPlayers           = 0;
            var maxPlayersPerDeployment = -1; // Will be initialized to numSimPlayers

            if (launchSimPlayerDeployment)
            {
                simDeploymentBaseName = args[10];
                simDeploymentJson     = args[11];
                simDeploymentRegion   = args[12];
                simDeploymentCluster  = args[13];

                if (!Int32.TryParse(args[14], out numSimPlayers))
                {
                    Console.WriteLine("Cannot parse the number of simulated players to connect.");
                    return(1);
                }
                else if (numSimPlayers <= 0)
                {
                    Console.WriteLine("The number of players must be positive.");
                    return(1);
                }

                // Start a single deployment by default
                maxPlayersPerDeployment = numSimPlayers;
                if (args.Length >= 16)
                {
                    if (!Int32.TryParse(args[15], out maxPlayersPerDeployment))
                    {
                        Console.WriteLine("Cannot parse the maximum number of simulated players per deployment.");
                        return(1);
                    }
                    else if (maxPlayersPerDeployment <= 0)
                    {
                        Console.WriteLine("The maximum number of simulated players per deployment must be positive.");
                        return(1);
                    }
                }
            }

            try
            {
                var deploymentServiceClient = DeploymentServiceClient.Create(GetApiEndpoint(useChinaPlatform), GetPlatformRefreshTokenCredential(useChinaPlatform));

                if (DeploymentExists(deploymentServiceClient, projectName, mainDeploymentName))
                {
                    StopDeploymentByName(deploymentServiceClient, projectName, mainDeploymentName);
                }

                var createMainDeploymentOp = CreateMainDeploymentAsync(deploymentServiceClient,
                                                                       launchSimPlayerDeployment, projectName, assemblyName, runtimeVersion,
                                                                       mainDeploymentName, mainDeploymentJsonPath, mainDeploymentSnapshotPath,
                                                                       mainDeploymentRegion, mainDeploymentCluster, mainDeploymentTags, useChinaPlatform);

                if (!launchSimPlayerDeployment)
                {
                    // Don't launch a simulated player deployment. Wait for main deployment to be created and then return.
                    Console.WriteLine("Waiting for the main deployment to be ready...");
                    var result = createMainDeploymentOp.PollUntilCompleted().GetResultOrNull();
                    if (result == null)
                    {
                        Console.WriteLine("Failed to create the main deployment");
                        return(1);
                    }

                    Console.WriteLine("Successfully created the main deployment");
                    return(0);
                }

                // We are using the main deployment snapshot also for the sim player deployment(s), because we only need to specify a snapshot
                // to be able to start the deployment. The sim players don't care about the actual snapshot.
                var simDeploymentCreationOps = CreateSimPlayerDeploymentsAsync(deploymentServiceClient,
                                                                               projectName, assemblyName, runtimeVersion, mainDeploymentName, simDeploymentBaseName,
                                                                               simDeploymentJson, mainDeploymentSnapshotPath, simDeploymentRegion, simDeploymentCluster,
                                                                               numSimPlayers, maxPlayersPerDeployment, useChinaPlatform);

                if (simDeploymentCreationOps == null || simDeploymentCreationOps.Count == 0)
                {
                    Console.WriteLine("Failed to start any simulated player deployments.");
                    return(1);
                }

                // Wait for the main deployment to be ready
                Console.WriteLine("Waiting for the main deployment to be ready...");
                var mainDeploymentResult = createMainDeploymentOp.PollUntilCompleted().GetResultOrNull();
                if (mainDeploymentResult == null)
                {
                    Console.WriteLine("Failed to create the main deployment");
                    return(1);
                }
                Console.WriteLine("Successfully created the main deployment");

                // Waiting for the simulated player deployment(s) to be ready
                var numSuccessfullyStartedSimDeployments = 0;
                for (var simDeploymentIndex = 0; simDeploymentIndex < simDeploymentCreationOps.Count; simDeploymentIndex++)
                {
                    var deploymentDescription = $"(deployment {simDeploymentIndex + 1}/{simDeploymentCreationOps.Count})";
                    Console.WriteLine($"Waiting for the simulated player deployment to be ready... {deploymentDescription}");

                    var simPlayerDeployment = simDeploymentCreationOps[simDeploymentIndex].PollUntilCompleted().GetResultOrNull();
                    if (simPlayerDeployment == null)
                    {
                        Console.WriteLine($"Failed to create the simulated player deployment {deploymentDescription}");
                        continue;
                    }

                    Console.WriteLine($"Deployment startup complete!");

                    numSuccessfullyStartedSimDeployments++;
                }

                Console.WriteLine($"Successfully started {numSuccessfullyStartedSimDeployments} out of {simDeploymentCreationOps.Count} simulated player deployments.");
            }
            catch (Grpc.Core.RpcException e)
            {
                if (e.Status.StatusCode == Grpc.Core.StatusCode.NotFound)
                {
                    Console.WriteLine($"Unable to launch the deployment(s). This is likely because the project '{projectName}' or assembly '{assemblyName}' doesn't exist.");
                    Console.WriteLine($"Detail: '{e.Status.Detail}'");
                }
                else if (e.Status.StatusCode == Grpc.Core.StatusCode.ResourceExhausted)
                {
                    Console.WriteLine($"Unable to launch the deployment(s). Cloud cluster resources exhausted, Detail: '{e.Status.Detail}'");
                }
                else
                {
                    Console.WriteLine($"Unable to launch the deployment(s). Detail: '{e.Status.Detail}'");
                }

                return(1);
            }

            return(0);
        }
        private static int CreateSimDeployments(string[] args, bool useChinaPlatform)
        {
            var projectName               = args[1];
            var assemblyName              = args[2];
            var runtimeVersion            = args[3];
            var targetDeploymentName      = args[4];
            var simDeploymentBaseName     = args[5];
            var simDeploymentJson         = args[6];
            var simDeploymentRegion       = args[7];
            var simDeploymentCluster      = args[8];
            var simDeploymentSnapshotPath = args[9];
            var numSimplayers             = 0;

            if (!Int32.TryParse(args[10], out numSimplayers))
            {
                Console.WriteLine("Cannot parse the number of simulated players to connect.");
                return(1);
            }
            else if (numSimplayers <= 0)
            {
                Console.WriteLine("The number of players must be positive.");
                return(1);
            }

            var autoConnect = false;

            if (!Boolean.TryParse(args[12], out autoConnect))
            {
                Console.WriteLine("Cannot parse the auto-connect flag.");
                return(1);
            }

            var maxPlayersPerDeployment = numSimplayers;

            if (args.Length >= 12)
            {
                if (!Int32.TryParse(args[11], out maxPlayersPerDeployment))
                {
                    Console.WriteLine("Cannot parse the maximum number of simulated players per deployments.");
                    return(1);
                }
                else if (maxPlayersPerDeployment <= 0)
                {
                    Console.WriteLine("The maximum number of simulated players per deployment must be positive.");
                    return(1);
                }
            }

            var deploymentServiceClient = DeploymentServiceClient.Create(GetApiEndpoint(useChinaPlatform));

            var simDeploymentCreationOps = CreateSimPlayerDeploymentsAsync(deploymentServiceClient,
                                                                           projectName, assemblyName, runtimeVersion, targetDeploymentName, simDeploymentBaseName,
                                                                           simDeploymentJson, simDeploymentSnapshotPath, simDeploymentRegion, simDeploymentCluster,
                                                                           numSimplayers, maxPlayersPerDeployment, useChinaPlatform);

            if (simDeploymentCreationOps == null || simDeploymentCreationOps.Count == 0)
            {
                Console.WriteLine("Failed to start any simulated player deployments.");
                return(1);
            }

            var numSuccessfullyStartedDeployments = 0;

            for (var simDeploymentIndex = 0; simDeploymentIndex < simDeploymentCreationOps.Count; simDeploymentIndex++)
            {
                var deploymentDescription = $"(deployment {simDeploymentIndex + 1}/{simDeploymentCreationOps.Count})";
                Console.WriteLine($"Waiting for the simulated player deployment to be ready... {deploymentDescription}");

                var simPlayerDeployment = simDeploymentCreationOps[simDeploymentIndex].PollUntilCompleted().GetResultOrNull();
                if (simPlayerDeployment == null)
                {
                    Console.WriteLine($"Failed to create the simulated player deployment {deploymentDescription}");
                    continue;
                }

                Console.WriteLine($"Deployment startup complete!");

                numSuccessfullyStartedDeployments++;
            }

            Console.WriteLine($"Successfully started {numSuccessfullyStartedDeployments} out of {simDeploymentCreationOps.Count} simulated player deployments.");

            return(0);
        }
Exemple #26
0
        private static int CreateDeployment(string[] args)
        {
            bool launchSimPlayerDeployment = args.Length == 9;

            var projectName                    = args[1];
            var assemblyName                   = args[2];
            var mainDeploymentName             = args[3];
            var mainDeploymentJson             = args[4];
            var mainDeploymentSnapshotFilePath = args[5];
            var deploymentRegionCode           = args[6];

            var simDeploymentName = string.Empty;
            var simDeploymentJson = string.Empty;

            if (launchSimPlayerDeployment)
            {
                simDeploymentName = args[7];
                simDeploymentJson = args[8];
            }

            // Create service clients.
            var playerAuthServiceClient = PlayerAuthServiceClient.Create();
            var snapshotServiceClient   = SnapshotServiceClient.Create();
            var deploymentServiceClient = DeploymentServiceClient.Create();

            try
            {
                // Upload snapshots.
                var mainSnapshotId = UploadSnapshot(snapshotServiceClient, mainDeploymentSnapshotFilePath, projectName,
                                                    mainDeploymentName);

                if (mainSnapshotId.Length == 0)
                {
                    return(1);
                }

                // Create main deployment.
                var mainDeploymentConfig = new Deployment
                {
                    AssemblyId   = assemblyName,
                    LaunchConfig = new LaunchConfig
                    {
                        ConfigJson = File.ReadAllText(mainDeploymentJson)
                    },
                    Name               = mainDeploymentName,
                    ProjectName        = projectName,
                    StartingSnapshotId = mainSnapshotId,
                    RegionCode         = deploymentRegionCode
                };

                if (launchSimPlayerDeployment)
                {
                    // This tag needs to be added to allow simulated clients to connect using login
                    // tokens generated with anonymous auth.
                    mainDeploymentConfig.Tag.Add("dev_login");
                }

                Console.WriteLine(
                    $"Creating the main deployment {mainDeploymentName} in project {projectName} with snapshot ID {mainSnapshotId}.");

                var mainDeploymentCreateOp = deploymentServiceClient.CreateDeployment(new CreateDeploymentRequest
                {
                    Deployment = mainDeploymentConfig
                }).PollUntilCompleted();

                Console.WriteLine("Successfully created the main deployment.");

                if (launchSimPlayerDeployment)
                {
                    // Create development authentication token used by the simulated players.
                    var dat = playerAuthServiceClient.CreateDevelopmentAuthenticationToken(
                        new CreateDevelopmentAuthenticationTokenRequest
                    {
                        Description = "DAT for sim worker deployment.",
                        Lifetime    = Duration.FromTimeSpan(new TimeSpan(7, 0, 0, 0)),
                        ProjectName = projectName
                    });

                    // Add worker flags to sim deployment JSON.
                    var devAuthTokenIdFlag = new JObject();
                    devAuthTokenIdFlag.Add("name", "fps_simulated_players_dev_auth_token_id");
                    devAuthTokenIdFlag.Add("value", dat.DevelopmentAuthenticationToken.Id);

                    var targetDeploymentFlag = new JObject();
                    targetDeploymentFlag.Add("name", "fps_simulated_players_target_deployment");
                    targetDeploymentFlag.Add("value", mainDeploymentName);

                    var     simWorkerConfigJson = File.ReadAllText(simDeploymentJson);
                    dynamic simWorkerConfig     = JObject.Parse(simWorkerConfigJson);

                    for (var i = 0; i < simWorkerConfig.workers.Count; ++i)
                    {
                        if (simWorkerConfig.workers[i].worker_type == "SimulatedPlayerCoordinator")
                        {
                            simWorkerConfig.workers[i].flags.Add(devAuthTokenIdFlag);
                            simWorkerConfig.workers[i].flags.Add(targetDeploymentFlag);
                        }
                    }

                    simWorkerConfigJson = simWorkerConfig.ToString();

                    // Create simulated player deployment.
                    var simDeploymentConfig = new Deployment
                    {
                        AssemblyId   = assemblyName,
                        LaunchConfig = new LaunchConfig
                        {
                            ConfigJson = simWorkerConfigJson
                        },
                        Name        = simDeploymentName,
                        ProjectName = projectName,
                        RegionCode  = deploymentRegionCode
                    };

                    simDeploymentConfig.Tag.Add("simulated_clients");

                    Console.WriteLine($"Creating the simulated player deployment {simDeploymentName} in project {projectName}.");

                    var simDeploymentCreateOp = deploymentServiceClient.CreateDeployment(new CreateDeploymentRequest
                    {
                        Deployment = simDeploymentConfig
                    }).PollUntilCompleted();

                    Console.WriteLine("Successfully created the simulated player deployment.");
                }
            }
            catch (Grpc.Core.RpcException e)
            {
                if (e.Status.StatusCode == Grpc.Core.StatusCode.NotFound)
                {
                    Console.WriteLine(
                        $"Unable to launch the deployment(s). This is likely because the project '{projectName}' or assembly '{assemblyName}' doesn't exist.");
                }
                else
                {
                    throw;
                }
            }

            return(0);
        }
Exemple #27
0
        private static int CreateDeployment(string[] args)
        {
            bool launchSimPlayerDeployment = args.Length == 15;

            var projectName                = args[1];
            var assemblyName               = args[2];
            var runtimeVersion             = args[3];
            var mainDeploymentName         = args[4];
            var mainDeploymentJsonPath     = args[5];
            var mainDeploymentSnapshotPath = args[6];
            var mainDeploymentRegion       = args[7];
            var mainDeploymentCluster      = args[8];
            var mainDeploymentTags         = args[9];

            var simDeploymentName    = string.Empty;
            var simDeploymentJson    = string.Empty;
            var simDeploymentRegion  = string.Empty;
            var simDeploymentCluster = string.Empty;
            var simNumPlayers        = 0;

            if (launchSimPlayerDeployment)
            {
                simDeploymentName    = args[10];
                simDeploymentJson    = args[11];
                simDeploymentRegion  = args[12];
                simDeploymentCluster = args[13];

                if (!Int32.TryParse(args[14], out simNumPlayers))
                {
                    Console.WriteLine("Cannot parse the number of simulated players to connect.");
                    return(1);
                }
            }

            try
            {
                var deploymentServiceClient = DeploymentServiceClient.Create(GetApiEndpoint(mainDeploymentRegion), GetPlatformRefreshTokenCredential(mainDeploymentRegion));

                if (DeploymentExists(deploymentServiceClient, projectName, mainDeploymentName))
                {
                    StopDeploymentByName(deploymentServiceClient, projectName, mainDeploymentName);
                }

                var createMainDeploymentOp = CreateMainDeploymentAsync(deploymentServiceClient, launchSimPlayerDeployment, projectName, assemblyName, runtimeVersion, mainDeploymentName, mainDeploymentJsonPath, mainDeploymentSnapshotPath, mainDeploymentRegion, mainDeploymentCluster, mainDeploymentTags);

                if (launchSimPlayerDeployment && DeploymentExists(deploymentServiceClient, projectName, simDeploymentName))
                {
                    StopDeploymentByName(deploymentServiceClient, projectName, simDeploymentName);
                }

                // TODO: UNR-3550 - Re-add dynamic worker flags when supported with new runtime.
                // We need to wait for the main deployment to be finished starting before we can launch the sim player deployment.
                Console.WriteLine("Waiting for deployment to be ready...");
                var result = createMainDeploymentOp.PollUntilCompleted().GetResultOrNull();
                if (result == null)
                {
                    Console.WriteLine("Failed to create the main deployment");
                    return(1);
                }

                Console.WriteLine("Successfully created the main deployment");

                if (launchSimPlayerDeployment)
                {
                    var createSimDeploymentOp = CreateSimPlayerDeploymentAsync(deploymentServiceClient, projectName, assemblyName, runtimeVersion, mainDeploymentName, simDeploymentName, simDeploymentJson, simDeploymentRegion, simDeploymentCluster, simNumPlayers);

                    // Wait for both deployments to be created.
                    Console.WriteLine("Waiting for simulated player deployment to be ready...");

                    var simPlayerDeployment = createSimDeploymentOp.PollUntilCompleted().GetResultOrNull();
                    if (simPlayerDeployment == null)
                    {
                        Console.WriteLine("Failed to create the simulated player deployment");
                        return(1);
                    }

                    Console.WriteLine("Done! Simulated players will start to connect to your deployment");
                }
            }
            catch (Grpc.Core.RpcException e)
            {
                if (e.Status.StatusCode == Grpc.Core.StatusCode.NotFound)
                {
                    Console.WriteLine($"Unable to launch the deployment(s). This is likely because the project '{projectName}' or assembly '{assemblyName}' doesn't exist.");
                    Console.WriteLine($"Detail: '{e.Status.Detail}'");
                }
                else if (e.Status.StatusCode == Grpc.Core.StatusCode.ResourceExhausted)
                {
                    Console.WriteLine($"Unable to launch the deployment(s). Cloud cluster resources exhausted, Detail: '{e.Status.Detail}'");
                }
                else
                {
                    Console.WriteLine($"Unable to launch the deployment(s). Detail: '{e.Status.Detail}'");
                }

                return(1);
            }

            return(0);
        }
Exemple #28
0
        private static int CreateSimDeployments(string[] args)
        {
            var projectName          = args[1];
            var assemblyName         = args[2];
            var runtimeVersion       = args[3];
            var targetDeploymentName = args[4];
            var simDeploymentName    = args[5];
            var simDeploymentJson    = args[6];
            var simDeploymentRegion  = args[7];
            var simDeploymentCluster = args[8];

            var simNumPlayers = 0;

            if (!Int32.TryParse(args[9], out simNumPlayers))
            {
                Console.WriteLine("Cannot parse the number of simulated players to connect.");
                return(1);
            }

            var autoConnect = false;

            if (!Boolean.TryParse(args[10], out autoConnect))
            {
                Console.WriteLine("Cannot parse the auto-connect flag.");
                return(1);
            }

            try
            {
                var deploymentServiceClient = DeploymentServiceClient.Create(GetApiEndpoint(simDeploymentRegion));

                if (DeploymentExists(deploymentServiceClient, projectName, simDeploymentName))
                {
                    StopDeploymentByName(deploymentServiceClient, projectName, simDeploymentName);
                }

                var createSimDeploymentOp = CreateSimPlayerDeploymentAsync(deploymentServiceClient, projectName, assemblyName, runtimeVersion, targetDeploymentName, simDeploymentName, simDeploymentJson, simDeploymentRegion, simDeploymentCluster, simNumPlayers);

                // Wait for both deployments to be created.
                Console.WriteLine("Waiting for the simulated player deployment to be ready...");
                var simPlayerDeployment = createSimDeploymentOp.PollUntilCompleted().GetResultOrNull();
                if (simPlayerDeployment == null)
                {
                    Console.WriteLine("Failed to create the simulated player deployment");
                    return(1);
                }

                Console.WriteLine("Successfully created the simulated player deployment");

                // Update coordinator worker flag for simulated player deployment to notify target deployment is ready.
                simPlayerDeployment.WorkerFlags.Add(new WorkerFlag
                {
                    Key        = "target_deployment_ready",
                    Value      = autoConnect.ToString(),
                    WorkerType = CoordinatorWorkerName
                });
                deploymentServiceClient.UpdateDeployment(new UpdateDeploymentRequest {
                    Deployment = simPlayerDeployment
                });

                Console.WriteLine("Done! Simulated players will start to connect to your deployment");
            }
            catch (Grpc.Core.RpcException e)
            {
                if (e.Status.StatusCode == Grpc.Core.StatusCode.NotFound)
                {
                    Console.WriteLine(
                        $"Unable to launch the deployment(s). This is likely because the project '{projectName}' or assembly '{assemblyName}' doesn't exist.");
                }
                else
                {
                    throw;
                }
            }

            return(0);
        }
Exemple #29
0
        private static int CreateDeployment(string[] args)
        {
            bool launchSimPlayerDeployment = args.Length == 15;

            var projectName                = args[1];
            var assemblyName               = args[2];
            var runtimeVersion             = args[3];
            var mainDeploymentName         = args[4];
            var mainDeploymentJsonPath     = args[5];
            var mainDeploymentSnapshotPath = args[6];
            var mainDeploymentRegion       = args[7];
            var mainDeploymentCluster      = args[8];
            var mainDeploymentTags         = args[9];

            var simDeploymentName    = string.Empty;
            var simDeploymentJson    = string.Empty;
            var simDeploymentRegion  = string.Empty;
            var simDeploymentCluster = string.Empty;
            var simNumPlayers        = 0;

            if (launchSimPlayerDeployment)
            {
                simDeploymentName    = args[10];
                simDeploymentJson    = args[11];
                simDeploymentRegion  = args[12];
                simDeploymentCluster = args[13];

                if (!Int32.TryParse(args[14], out simNumPlayers))
                {
                    Console.WriteLine("Cannot parse the number of simulated players to connect.");
                    return(1);
                }
            }

            try
            {
                var deploymentServiceClient = DeploymentServiceClient.Create(GetApiEndpoint(mainDeploymentRegion), GetPlatformRefreshTokenCredential(mainDeploymentRegion));

                if (DeploymentExists(deploymentServiceClient, projectName, mainDeploymentName))
                {
                    StopDeploymentByName(deploymentServiceClient, projectName, mainDeploymentName);
                }

                var createMainDeploymentOp = CreateMainDeploymentAsync(deploymentServiceClient, launchSimPlayerDeployment, projectName, assemblyName, runtimeVersion, mainDeploymentName, mainDeploymentJsonPath, mainDeploymentSnapshotPath, mainDeploymentRegion, mainDeploymentCluster, mainDeploymentTags);

                if (!launchSimPlayerDeployment)
                {
                    // Don't launch a simulated player deployment. Wait for main deployment to be created and then return.
                    Console.WriteLine("Waiting for deployment to be ready...");
                    var result = createMainDeploymentOp.PollUntilCompleted().GetResultOrNull();
                    if (result == null)
                    {
                        Console.WriteLine("Failed to create the main deployment");
                        return(1);
                    }

                    Console.WriteLine("Successfully created the main deployment");
                    return(0);
                }

                if (DeploymentExists(deploymentServiceClient, projectName, simDeploymentName))
                {
                    StopDeploymentByName(deploymentServiceClient, projectName, simDeploymentName);
                }

                var createSimDeploymentOp = CreateSimPlayerDeploymentAsync(deploymentServiceClient, projectName, assemblyName, runtimeVersion, mainDeploymentName, simDeploymentName, simDeploymentJson, simDeploymentRegion, simDeploymentCluster, simNumPlayers);

                // Wait for both deployments to be created.
                Console.WriteLine("Waiting for deployments to be ready...");
                var mainDeploymentResult = createMainDeploymentOp.PollUntilCompleted().GetResultOrNull();
                if (mainDeploymentResult == null)
                {
                    Console.WriteLine("Failed to create the main deployment");
                    return(1);
                }

                Console.WriteLine("Successfully created the main deployment");
                var simPlayerDeployment = createSimDeploymentOp.PollUntilCompleted().GetResultOrNull();
                if (simPlayerDeployment == null)
                {
                    Console.WriteLine("Failed to create the simulated player deployment");
                    return(1);
                }

                Console.WriteLine("Successfully created the simulated player deployment");

                // Update coordinator worker flag for simulated player deployment to notify target deployment is ready.
                simPlayerDeployment.WorkerFlags.Add(new WorkerFlag
                {
                    Key        = "target_deployment_ready",
                    Value      = "true",
                    WorkerType = CoordinatorWorkerName
                });
                deploymentServiceClient.UpdateDeployment(new UpdateDeploymentRequest {
                    Deployment = simPlayerDeployment
                });

                Console.WriteLine("Done! Simulated players will start to connect to your deployment");
            }
            catch (Grpc.Core.RpcException e)
            {
                if (e.Status.StatusCode == Grpc.Core.StatusCode.NotFound)
                {
                    Console.WriteLine($"Unable to launch the deployment(s). This is likely because the project '{projectName}' or assembly '{assemblyName}' doesn't exist.");
                    Console.WriteLine($"Detail: '{e.Status.Detail}'");
                }
                else if (e.Status.StatusCode == Grpc.Core.StatusCode.ResourceExhausted)
                {
                    Console.WriteLine($"Unable to launch the deployment(s). Cloud cluster resources exhausted, Detail: '{e.Status.Detail}'");
                }
                else
                {
                    Console.WriteLine($"Unable to launch the deployment(s). Detail: '{e.Status.Detail}'");
                }

                return(1);
            }

            return(0);
        }
        private static int CreateDeploymentInternal <TOptions>(TOptions options, Func <TOptions, string> getLaunchConfigJson)
            where TOptions : Options.Create
        {
            var snapshotServiceClient   = SnapshotServiceClient.Create();
            var deploymentServiceClient = DeploymentServiceClient.Create();

            try
            {
                var deployment = new Deployment
                {
                    AssemblyId   = options.AssemblyName,
                    LaunchConfig = new LaunchConfig
                    {
                        ConfigJson = getLaunchConfigJson(options)
                    },
                    Name        = options.DeploymentName,
                    ProjectName = options.ProjectName,
                    RegionCode  = options.Region.ToString()
                };

                if (options.SnapshotPath != null)
                {
                    var snapshotId = UploadSnapshot(snapshotServiceClient, options.SnapshotPath, options.ProjectName,
                                                    options.DeploymentName);

                    if (string.IsNullOrEmpty(snapshotId))
                    {
                        return(Program.ErrorExitCode);
                    }

                    deployment.StartingSnapshotId = snapshotId;
                }

                if (options.Tags != null)
                {
                    foreach (var tag in options.Tags)
                    {
                        deployment.Tag.Add(tag);
                    }
                }

                var deploymentOp = deploymentServiceClient.CreateDeployment(new CreateDeploymentRequest
                {
                    Deployment = deployment
                }).PollUntilCompleted();

                if (deploymentOp.Result.Status != Deployment.Types.Status.Running)
                {
                    Ipc.WriteError(Ipc.ErrorCode.Unknown, "Deployment failed to start for an unknown reason.");
                    return(Program.ErrorExitCode);
                }
            }
            catch (Grpc.Core.RpcException e)
            {
                if (e.Status.StatusCode == Grpc.Core.StatusCode.NotFound)
                {
                    Ipc.WriteError(Ipc.ErrorCode.NotFound, e.Status.Detail);
                    return(Program.ErrorExitCode);
                }

                throw;
            }

            return(Program.SuccessExitCode);
        }