/// <summary> /// Translates an Azure-specific CloudDetails object into a /// generic JobDetails object which can be passed back to the /// presenter. /// </summary> /// <param name="cloudJob">The Azure ClouJob object.</param> /// <param name="ct">Cancellation token.</param> private async Task <JobDetails> GetJobDetails(CloudJob cloudJob, CancellationToken ct) { try { if (!await storageClient.GetContainerReference($"job-{cloudJob.Id}").ExistsAsync(ct)) { await DeleteJobAsync(cloudJob.Id, ct); return(null); } string owner = await GetContainerMetaDataAsync($"job-{cloudJob.Id}", "Owner", ct); TaskCounts tasks = await batchClient.JobOperations.GetJobTaskCountsAsync(cloudJob.Id, cancellationToken : ct); int numTasks = tasks.Active + tasks.Running + tasks.Completed; // If there are no tasks, set progress to 100%. double jobProgress = numTasks == 0 ? 100 : 100.0 * tasks.Completed / numTasks; // If cpu time is unavailable, set this field to 0. TimeSpan cpu = cloudJob.Statistics == null ? TimeSpan.Zero : cloudJob.Statistics.KernelCpuTime + cloudJob.Statistics.UserCpuTime; JobDetails job = new JobDetails { Id = cloudJob.Id, DisplayName = cloudJob.DisplayName, State = cloudJob.State.ToString(), Owner = owner, NumSims = numTasks - 1, // subtract one because one of these is the job manager Progress = jobProgress, CpuTime = cpu }; if (cloudJob.ExecutionInformation != null) { job.StartTime = cloudJob.ExecutionInformation.StartTime; job.EndTime = cloudJob.ExecutionInformation.EndTime; } return(job); } catch (Exception) { return(null); } }
/// <summary> /// Gets the list of jobs submitted to Azure. /// </summary> /// <returns>List of Jobs. Null if the thread is asked to cancel, or if unable to update the progress bar.</returns> private List <JobDetails> ListJobs() { try { view.ShowLoadingProgressBar(); view.JobLoadProgress = 0; } catch (NullReferenceException) { return(null); } catch (Exception e) { ShowError(e.ToString()); } List <JobDetails> jobs = new List <JobDetails>(); var pools = batchClient.PoolOperations.ListPools(); var jobDetailLevel = new ODATADetailLevel { SelectClause = "id,displayName,state,executionInfo,stats", ExpandClause = "stats" }; IPagedEnumerable <CloudJob> cloudJobs = null; // Attempt to download raw job list. If this fails more than 3 times, return. int numTries = 0; while (numTries < 4 && cloudJobs == null) { try { cloudJobs = batchClient.JobOperations.ListJobs(jobDetailLevel); } catch (Exception e) { if (numTries >= 3) { ShowError("Unable to retrieve job list: " + e.ToString()); return(new List <JobDetails>()); } } finally { numTries++; } } // Parse jobs into a list of JobDetails objects. var length = cloudJobs.Count(); int i = 0; foreach (var cloudJob in cloudJobs) { if (FetchJobs.CancellationPending) { return(null); } try { view.JobLoadProgress = 100.0 * i / length; } catch (NullReferenceException) { return(null); } catch (Exception e) { ShowError(e.ToString()); } string owner = GetAzureMetaData("job-" + cloudJob.Id, "Owner"); long numTasks = 1; double jobProgress = 0; try { TaskCounts tasks = batchClient.JobOperations.GetJobTaskCounts(cloudJob.Id); numTasks = tasks.Active + tasks.Running + tasks.Completed; // if there are no tasks, set progress to 100% jobProgress = numTasks == 0 ? 100 : 100.0 * tasks.Completed / numTasks; } catch (Exception e) { // sometimes an exception is thrown when retrieving the task counts // could be due to the job not being submitted correctly ShowError(e.ToString()); numTasks = -1; jobProgress = 100; } // if cpu time is unavailable, set this field to 0 TimeSpan cpu = cloudJob.Statistics == null ? TimeSpan.Zero : cloudJob.Statistics.KernelCpuTime + cloudJob.Statistics.UserCpuTime; var job = new JobDetails { Id = cloudJob.Id, DisplayName = cloudJob.DisplayName, State = cloudJob.State.ToString(), Owner = owner, NumSims = numTasks - 1, // subtract one because one of these is the job manager Progress = jobProgress, CpuTime = cpu }; if (cloudJob.ExecutionInformation != null) { job.StartTime = cloudJob.ExecutionInformation.StartTime; job.EndTime = cloudJob.ExecutionInformation.EndTime; } jobs.Add(job); i++; } view.HideLoadingProgressBar(); if (jobs == null) { return(new List <JobDetails>()); } return(jobs); }