Exemplo n.º 1
0
        public static async Task RunCompetitions(string mapPath, CompetetionMode competetionMode, CancellationToken cancellationToken = default)
        {
            switch (competetionMode)
            {
            case CompetetionMode.NoContainer:
                break;

            case CompetetionMode.ContainerPerCompetetion:
                await DockerService.BuildImageAsync(Directory.GetCurrentDirectory(), Program.DockerImageName, cancellationToken);

                await DockerService.StopAndRemoveAllContainersAsync(cancellationToken);

                break;

            case CompetetionMode.ReusableContainer:
                await DockerService.BuildImageAsync(Directory.GetCurrentDirectory(), Program.DockerImageName, cancellationToken);

                await DockerService.StopAndRemoveAllContainersAsync(cancellationToken);

                await ContainerRepository.InitalizeContainers(_geneProcessLimit, Program.DockerImageName, cancellationToken);

                break;
            }

            _arenaStartTime = DateTime.Now;

            Console.WriteLine("welcome to Colosseum. enjoy the show :)");

            List <Gene> lastGeneration     = null;
            var         lastGenerationFile = new FileInfo("generationInfo.json");

            if (lastGenerationFile.Exists)
            {
                Console.WriteLine($"loading last generation from {lastGenerationFile.FullName}");
                try
                {
                    var content = await File.ReadAllTextAsync(lastGenerationFile.FullName, cancellationToken);

                    lastGeneration = JsonConvert.DeserializeObject <List <Gene> >(content);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"loading last generation failed. error:{Environment.NewLine}{ex}");
                }
            }

            var generationNumber = 1;

            var arenaDir = new DirectoryInfo("arena");

            arenaDir.Create();

            var currentRunDir = arenaDir.CreateSubdirectory(DateTime.Now.ToString("s").Replace(" ", "-").ToValidFileName());

            currentRunDir.Create();

            var port = _startPort;

            var cts = new CancellationTokenSource();

            cancellationToken.Register(() => cts.Cancel());

            while (true)
            {
                var generationProcessStartTime = DateTime.Now;

                var generationDir = currentRunDir.CreateSubdirectory(generationNumber.ToString());
                generationDir.Create();

                var newGeneration = _generationGenerator.Genetic(lastGeneration);
                lastGeneration = new List <Gene>();

                var competitionTasks = new List <Task>();

                switch (competetionMode)
                {
                case CompetetionMode.NoContainer:
                    await cleanSystem(cancellationToken);

                    break;

                case CompetetionMode.ContainerPerCompetetion:
                    await DockerService.StopAndRemoveAllContainersAsync(cancellationToken);

                    break;

                case CompetetionMode.ReusableContainer:
                    break;
                }

                Console.WriteLine($"running generation #{generationNumber}");
                Console.WriteLine($"this generation will have {newGeneration.Count} genes and we'll process up to {_geneProcessLimit} genes simultaneously");
                Console.WriteLine("-----------");
                Console.WriteLine("no.\tsuccess\tscore\t\tid\t\telapsed\t\tsystem elapsed\t\tPPM\t\tcurrent time");

                foreach (var gene in newGeneration)
                {
                    competitionTasks.AddThreadSafe(processGene(gene, mapPath, lastGeneration, port, generationDir, competetionMode, cancellationToken));

                    port++;
                }

                await Task.WhenAll(competitionTasks).CancelOnFaulted(cts);

                var generationInfoFilePath = Path.Combine(generationDir.FullName, "generationInfo.json");
                await File.WriteAllTextAsync(generationInfoFilePath, JsonConvert.SerializeObject(newGeneration, Formatting.Indented), cancellationToken);

                var generationScoreAverage = newGeneration.Average(x => x.Score);
                Console.WriteLine($"generation score average: {generationScoreAverage}, generation elapsed time: {DateTime.Now - generationProcessStartTime}");

                generationNumber++;
            }
        }