Beispiel #1
0
        public async Task <ActionResult> JobFinishedAsync(string partitionKey, string rowKey, string key, string commit)
        {
            // Validate the key
            if (key != Startup.Configuration["ResultsCallbackKey"])
            {
                return(NotFound());
            }

            // Load the job details
            var connectionString    = Startup.Configuration.GetConnectionString("Storage");
            var tableStorageAccount = Microsoft.Azure.Cosmos.Table.CloudStorageAccount.Parse(connectionString);
            var tableClient         = tableStorageAccount.CreateCloudTableClient();
            var table = tableClient.GetTableReference("jobs");

            table.CreateIfNotExists();

            var job = table.CreateQuery <Job>()
                      .Where(j => j.PartitionKey == partitionKey && j.RowKey == rowKey)
                      .FirstOrDefault();

            if (job == null)
            {
                return(NotFound());
            }

            // Connect to Azure Batch
            var credentials = new BatchSharedKeyCredentials(
                Startup.Configuration["BatchAccountUrl"],
                Startup.Configuration["BatchAccountName"],
                Startup.Configuration["BatchAccountKey"]);

            using (var batchClient = BatchClient.Open(credentials))
            {
                var result      = "";
                var success     = false;
                var startTime   = (DateTime?)null;
                var endTime     = (DateTime?)null;
                var emailBody   = (string)null;
                var attachments = new CloudBlob[0];

                try
                {
                    var jobName = $"autotune-job-{rowKey}";

                    // Check if the Autotune job finished successfully
                    var autotune = batchClient.JobOperations.GetTask(jobName, "Autotune");
                    success   = autotune.ExecutionInformation.ExitCode == 0;
                    startTime = autotune.ExecutionInformation.StartTime;
                    endTime   = autotune.ExecutionInformation.EndTime;

                    // Connect to Azure Storage
                    var storageAccount  = Microsoft.Azure.Storage.CloudStorageAccount.Parse(connectionString);
                    var cloudBlobClient = storageAccount.CreateCloudBlobClient();

                    // Find the log file produced by Autotune
                    var container = cloudBlobClient.GetContainerReference(jobName);

                    if (success)
                    {
                        var blob = container.GetBlobReference("autotune_recommendations.log");

                        using (var stream = new MemoryStream())
                            using (var reader = new StreamReader(stream))
                            {
                                // Download the log file
                                blob.DownloadToStream(stream);
                                stream.Position = 0;

                                var recommendations = reader.ReadToEnd();

                                // Parse the results
                                var parsedResults = AutotuneResults.ParseResult(recommendations, job);
                                parsedResults.Commit = commit;

                                emailBody = await _viewRenderService.RenderToStringAsync("Results/Success", parsedResults);
                            }
                    }

                    // Get the log files to attach to the email
                    attachments = container.ListBlobs()
                                  .Select(b => new CloudBlockBlob(b.Uri, cloudBlobClient))
                                  .Where(b => b.Name != "autotune_recommendations.log" && b.Name != "profile.json")
                                  .ToArray();
                }
                catch (Exception ex)
                {
                    result  = ex.ToString();
                    success = false;
                }

                if (emailBody == null)
                {
                    emailBody = await _viewRenderService.RenderToStringAsync("Results/Failure", commit);
                }

                EmailResults(job.EmailResultsTo, emailBody, attachments);

                // Update the details in the table
                job.ProcessingStarted   = startTime;
                job.ProcessingCompleted = endTime;
                job.Result = result;
                job.Failed = !success;
                var update = TableOperation.Replace(job);
                await table.ExecuteAsync(update);

                // Store the commit hash to identify the version of Autotune that was used
                var commitSetting = new Settings();
                commitSetting.PartitionKey = "Commit";
                commitSetting.RowKey       = "";
                commitSetting.Value        = commit;
                var settingTable = tableClient.GetTableReference("settings");
                settingTable.CreateIfNotExists();
                var upsert = TableOperation.InsertOrReplace(commitSetting);
                settingTable.Execute(upsert);
            }

            return(Content(""));
        }
        public ActionResult JobFinished(int id, string key, string commit)
        {
            // Validate the key
            if (key != ConfigurationManager.AppSettings["ResultsCallbackKey"])
            {
                return(HttpNotFound());
            }

            ViewBag.Commit = commit;

            // Connect to Azure Batch
            var credentials = new BatchSharedKeyCredentials(
                ConfigurationManager.AppSettings["BatchAccountUrl"],
                ConfigurationManager.AppSettings["BatchAccountName"],
                ConfigurationManager.AppSettings["BatchAccountKey"]);

            using (var batchClient = BatchClient.Open(credentials))
                using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["Sql"].ConnectionString))
                {
                    con.Open();

                    // Load the job details from the database
                    var job = Job.Load(con, id);
                    if (job == null)
                    {
                        return(HttpNotFound());
                    }

                    var result      = "";
                    var success     = false;
                    var startTime   = (DateTime?)null;
                    var endTime     = (DateTime?)null;
                    var emailBody   = (string)null;
                    var attachments = new CloudBlob[0];

                    try
                    {
                        var jobName = $"autotune-job-{id}";

                        // Check if the Autotune job finished successfully
                        var autotune = batchClient.JobOperations.GetTask(jobName, "Autotune");
                        success   = autotune.ExecutionInformation.ExitCode == 0;
                        startTime = autotune.ExecutionInformation.StartTime;
                        endTime   = autotune.ExecutionInformation.EndTime;

                        // Connect to Azure Storage
                        var connectionString = ConfigurationManager.ConnectionStrings["Storage"].ConnectionString;
                        var storageAccount   = CloudStorageAccount.Parse(connectionString);
                        var cloudBlobClient  = storageAccount.CreateCloudBlobClient();

                        // Find the log file produced by Autotune
                        var container = cloudBlobClient.GetContainerReference(jobName);

                        if (success)
                        {
                            var blob = container.GetBlobReference("autotune_recommendations.log");

                            using (var stream = new MemoryStream())
                                using (var reader = new StreamReader(stream))
                                {
                                    // Download the log file
                                    blob.DownloadToStream(stream);
                                    stream.Position = 0;

                                    result = reader.ReadToEnd();

                                    // Parse the results
                                    var parsedResults = AutotuneResults.ParseResult(result, job);

                                    emailBody = RenderViewToString(ControllerContext, "Success", parsedResults);
                                }
                        }

                        // Get the log files to attach to the email
                        attachments = container.ListBlobs()
                                      .Select(b => new CloudBlockBlob(b.Uri, cloudBlobClient))
                                      .Where(b => b.Name != "autotune_recommendations.log" && b.Name != "profile.json")
                                      .ToArray();
                    }
                    catch (Exception ex)
                    {
                        result  = ex.ToString();
                        success = false;
                    }

                    if (emailBody == null)
                    {
                        emailBody = RenderViewToString(ControllerContext, "Failure");
                    }

                    EmailResults(job.EmailResultsTo, emailBody, attachments);

                    // Update the details in the SQL database
                    using (var cmd = con.CreateCommand())
                    {
                        cmd.CommandText = "UPDATE Jobs SET ProcessingStarted = @ProcessingStarted, ProcessingCompleted = @ProcessingCompleted, Result = @Result, Failed = @Failed WHERE JobID = @Id";
                        cmd.Parameters.AddWithValue("@Id", id);
                        cmd.Parameters.AddWithValue("@ProcessingStarted", (object)startTime ?? DBNull.Value);
                        cmd.Parameters.AddWithValue("@ProcessingCompleted", (object)endTime ?? DBNull.Value);
                        cmd.Parameters.AddWithValue("@Result", result);
                        cmd.Parameters.AddWithValue("@Failed", !success);
                        cmd.ExecuteNonQuery();
                    }

                    // Store the commit hash to identify the version of Autotune that was used
                    using (var cmd = con.CreateCommand())
                    {
                        cmd.CommandText = "UPDATE Settings SET Value = @commit WHERE Name = 'Commit'";
                        cmd.Parameters.AddWithValue("@Commit", commit);
                        cmd.ExecuteNonQuery();
                    }
                }

            return(Content(""));
        }
        public ActionResult Details(string nsUrl, string jobId)
        {
            var partitionKey = HomeController.GetPartitionKey(nsUrl);

            // Load the job details
            var connectionString    = Startup.Configuration.GetConnectionString("Storage");
            var tableStorageAccount = Microsoft.Azure.Cosmos.Table.CloudStorageAccount.Parse(connectionString);
            var tableClient         = tableStorageAccount.CreateCloudTableClient();
            var table = tableClient.GetTableReference("jobs");

            table.CreateIfNotExists();

            var job = table.CreateQuery <Job>()
                      .Where(j => j.PartitionKey == partitionKey && j.RowKey == jobId)
                      .FirstOrDefault();

            if (job == null)
            {
                return(NotFound());
            }

            // Connect to Azure Batch
            var credentials = new BatchSharedKeyCredentials(
                Startup.Configuration["BatchAccountUrl"],
                Startup.Configuration["BatchAccountName"],
                Startup.Configuration["BatchAccountKey"]);

            using (var batchClient = BatchClient.Open(credentials))
            {
                try
                {
                    var jobName = $"autotune-job-{jobId}";

                    // Check if the Autotune job finished successfully
                    var autotune = batchClient.JobOperations.GetTask(jobName, "Autotune");
                    var success  = autotune.ExecutionInformation.ExitCode == 0;

                    // Connect to Azure Storage
                    var storageAccount  = Microsoft.Azure.Storage.CloudStorageAccount.Parse(connectionString);
                    var cloudBlobClient = storageAccount.CreateCloudBlobClient();

                    // Find the log file produced by Autotune
                    var container = cloudBlobClient.GetContainerReference(jobName);

                    ViewBag.Logs = container.ListBlobs()
                                   .Select(b => new CloudBlockBlob(b.Uri, cloudBlobClient))
                                   .Where(b => b.Name != "autotune_recommendations.log" && b.Name != "profile.json")
                                   .Select(b => b.Name)
                                   .ToArray();

                    if (success)
                    {
                        var blob = container.GetBlobReference("autotune_recommendations.log");

                        using (var stream = new MemoryStream())
                            using (var reader = new StreamReader(stream))
                            {
                                // Download the log file
                                blob.DownloadToStream(stream);
                                stream.Position = 0;

                                var recommendations = reader.ReadToEnd();

                                // Parse the results
                                var parsedResults = AutotuneResults.ParseResult(recommendations, job);

                                return(View("SuccessDetails", parsedResults));
                            }
                    }
                }
                catch (StorageException ex)
                {
                    if (ex.RequestInformation.ErrorCode == "BlobNotFound")
                    {
                        return(View("JobExpired"));
                    }
                }
                catch
                {
                }

                return(View("FailureDetails", job));
            }
        }