public void Initialise() { Task.Run(async() => { while (true) { RunBuild currentBuild = null; currentBuild = await GetCurrentBuild(); IQueueBuilder queueBuilder = new RabbitBuilder(); using (ISender statusMessageSender = queueBuilder.ConfigureTransport(_queueServer, _queueVhost, _queueUsername, _queuePassword) .ISendTo(QueueNames.Status(currentBuild.Build)) .Build()) { try { Action <(string status, string warning, string error)> notify = ((string status, string warning, string error)state) => { if (!string.IsNullOrEmpty(state.status)) { Console.WriteLine($"INFO: {state.status}"); } if (!string.IsNullOrEmpty(state.warning)) { Console.WriteLine($"WARNING: {state.warning}"); } if (!string.IsNullOrEmpty(state.error)) { Console.WriteLine($"ERROR: {state.error}"); } statusMessageSender.Send(StatusReport(state)); }; await RunProcess(currentBuild, notify); } catch (Exception ex) { statusMessageSender.Send(StatusReport((null, null, SerialiseError(ex)))); // TODO : Log the exception // Rethrowing the exception from this point would kill the thread which we don't want to do } finally { RemoveBuild(currentBuild); } } } }, _cancellationToken); }
public static void RunBuild(RunBuild build) { IQueueBuilder queueBuilder = new RabbitBuilder(); List <Task> tasks = new List <Task>(); using (ISender statusMessageSender = queueBuilder.ConfigureTransport(_queueServer, _queueVhost, _queueUsername, _queuePassword) .ISendTo(QueueNames.Status(build.Build)) .Build()) { SendStatusMessage(statusMessageSender, $"Starting build {build.Build}"); } foreach (var proc in processes) { tasks.Add(proc.RunBuild(build)); } // Wait for at least one task to complete this build before moving onto the next build Task.WaitAny(tasks.ToArray()); // Don't send anymore messages to the status queue after this point as it might have been removed already // and we don't want to re-create it }
public async Task StartBuild(BuildRunRequest request) { try { ReportStatus($"[{request.Build}] Staring"); RunBuild buildInstruction = CreateBuildInstruction(request); string testOutput; using (DockerWrapper docker = new DockerWrapper()) { CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); //cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(60)); Dictionary <string, string> environmentVariable = new Dictionary <string, string> { { "TESTER_LISTTESTS", "true" } }; testOutput = await docker.Run(buildInstruction.Image, environmentVariables : environmentVariable, command : buildInstruction.Command, cancellationToken : cancellationTokenSource.Token); } List <RunTest> tests = new List <RunTest>(); string[] testNames = testOutput.Split('\n'); foreach (string testName in testNames) { if (!string.IsNullOrEmpty(testName)) { RunTest item = new RunTest { Build = request.Build, FullName = testName.Trim() }; tests.Add(item); } } AddTestsToDictionary(_expectedTests, tests); // Configure receivers statusMessageReceiver = ConfigureReceiver(QueueNames.Status(request.Build)); testResultReceiver = ConfigureReceiver(QueueNames.TestResponse(request.Build)); // Add all the tests to the queue ReportStatus($"[{request.Build}] Sending Test Instructions ..."); testInstructionSender = ConfigureSender(QueueNames.TestRequest(request.Build)); SendTestInstructions(testInstructionSender, tests); ReportStatus($"[{request.Build}] Test Instructions sent."); // Add the build instruction to the queue ReportStatus($"[{request.Build}] Sending Build Instruction ..."); buildInstructionSender = ConfigureSender(QueueNames.Build()); buildInstructionSender.Send(buildInstruction); ReportStatus($"[{request.Build}] Build Instruction sent."); // Subscribe to the test result queue until all the tests have been completed (notifying subscribers) testResultReceiver.Receive <TestResult>(TestResultReceived); statusMessageReceiver.Receive <StatusMessage>(StatusMessageReceived); // Wait for tests to complete await TestsStillRunning(_cancellationTokenSource.Token); ReportStatus($"DONE"); // Notify cubscribers that the run is complete _testResultMonitor.notifyComplete(); _statusMessageMonitor.notifyComplete(); } catch (Exception ex) { ReportError(ex.Message); } }