/// <summary> /// Force the recomputation of the cluster job list. /// </summary> /// <param name="virtualCluster">Virtual cluster to use (defined only for some cluster types).</param> /// <param name="manager">Communication manager.</param> protected override void RecomputeClusterJobList(string virtualCluster, CommManager manager) { this.clusterJobs = new Dictionary <string, ClusterJobInformation>(); var jobs = this.config.AzureClient.ExpandFileOrDirectory(AzureDfsFile.UriFromPath(this.config, "")).ToList(); int done = 0; foreach (var job in jobs) { manager.Token.ThrowIfCancellationRequested(); string jobRootFolder = AzureDfsFile.PathFromUri(this.config, job); ClusterJobInformation info = this.GetJobInfo(jobRootFolder); if (info != null) { // ReSharper disable once AssignNullToNotNullAttribute this.clusterJobs.Add(job.AbsolutePath, info); } manager.Progress(100 * done++ / jobs.Count); } manager.Progress(100); }
/// <summary> /// For a folder object, returns the contained file with the specified name. /// </summary> /// <param name="filename">File name within the folder.</param> /// <returns>The file within the folder.</returns> public override IClusterResidentObject GetFile(string filename) { this.PopulateCache(); string filepath; if (this.client != null) { filepath = this.client.Combine(this.path, filename); } else { filepath = Path.Combine(this.path, filename); } bool isFolder = false; bool isDfsStream = false; long sz = -1; if (blocks.ContainsKey(filepath)) { isDfsStream = true; sz = blocks[filepath]; } else if (pages.ContainsKey(filepath)) { isDfsStream = false; sz = pages[filepath]; } else if (this.client != null) { // if the client is null the information may be incorrect isFolder = true; } var file = new AzureDfsFile(this.Config, this.Job, this.client, filepath, this.ShouldCacheLocally, isFolder); file.IsDfsStream = isDfsStream; file.size = sz; return(file); }
/// <summary> /// If the current object is a folder, it returns the contained objects. /// </summary> /// <returns>An iterator over all contained objects that match the specified string.</returns> /// <param name="match">A shell expression (similar to the argument of Directory.GetFiles()).</param> public override IEnumerable <IClusterResidentObject> GetFilesAndFolders(string match) { this.PopulateCache(); long length = -1; foreach (var child in this.client.EnumerateDirectory(this.path)) { Regex re = Utilities.RegexFromSearchPattern(match); if (!re.IsMatch(child)) { continue; } bool isFolder = false; bool isDfsStream = false; if (blocks.ContainsKey(child)) { isDfsStream = true; length = blocks[child]; } else if (pages.ContainsKey(child)) { isDfsStream = false; length = pages[child]; } else if (this.client != null) { // otherwise this information may be incorrect isFolder = true; } var file = new AzureDfsFile(this.Config, this.Job, this.client, child, this.ShouldCacheLocally, isFolder); file.IsDfsStream = isDfsStream; file.size = length; yield return(file); } }
/// <summary> /// Extract the job information from a folder with logs on the local machine. /// </summary> /// <param name="jobRootFolder">Folder with logs for the specified job.</param> /// <returns>The job information, or null if not found.</returns> private ClusterJobInformation GetJobInfo(string jobRootFolder) { DateTime date = DateTime.MinValue; DateTime lastHeartBeat = DateTime.MinValue; ClusterJobInformation.ClusterJobStatus status = ClusterJobInformation.ClusterJobStatus.Unknown; bool found = false; Uri uri = AzureDfsFile.UriFromPath(this.config, jobRootFolder); var jobsFolders = this.config.AzureClient.ExpandFileOrDirectory(uri).ToList(); jobRootFolder = GetBlobName(this.config.Container, jobRootFolder); string jobName = jobRootFolder; foreach (var file in jobsFolders) { if (file.AbsolutePath.EndsWith("heartbeat")) { string blobName = GetBlobName(this.config.Container, file.AbsolutePath); var blob = this.config.AzureClient.Container.GetPageBlobReference(blobName); blob.FetchAttributes(); var props = blob.Metadata; if (props.ContainsKey("status")) { var st = props["status"]; switch (st) { case "failure": status = ClusterJobInformation.ClusterJobStatus.Failed; break; case "success": status = ClusterJobInformation.ClusterJobStatus.Succeeded; break; case "running": status = ClusterJobInformation.ClusterJobStatus.Running; break; case "killed": status = ClusterJobInformation.ClusterJobStatus.Cancelled; break; default: Console.WriteLine("Unknown status " + st); break; } } if (props.ContainsKey("heartbeat")) { var hb = props["heartbeat"]; if (DateTime.TryParse(hb, out lastHeartBeat)) { lastHeartBeat = lastHeartBeat.ToLocalTime(); if (status == ClusterJobInformation.ClusterJobStatus.Running && DateTime.Now - lastHeartBeat > TimeSpan.FromSeconds(40)) { // job has in fact crashed status = ClusterJobInformation.ClusterJobStatus.Failed; } } } if (props.ContainsKey("jobname")) { jobName = props["jobname"]; } if (props.ContainsKey("starttime")) { var t = props["starttime"]; if (DateTime.TryParse(t, out date)) { date = date.ToLocalTime(); } } found = true; } else if (file.AbsolutePath.Contains("DryadLinqProgram__") && // newer heartbeats contain the date date != DateTime.MinValue) { var blob = this.config.AzureClient.Container.GetBlockBlobReference(AzureDfsFile.PathFromUri(this.config, file)); blob.FetchAttributes(); var props = blob.Properties; if (props.LastModified.HasValue) { date = props.LastModified.Value.DateTime; date = date.ToLocalTime(); } } } if (!found) { return(null); } TimeSpan running = TimeSpan.Zero; if (date != DateTime.MinValue && lastHeartBeat != DateTime.MinValue) { running = lastHeartBeat - date; } var info = new ClusterJobInformation(this.config.Name, "", jobRootFolder, jobName, Environment.UserName, date, running, status); return(info); }
/// <summary> /// For a folder object, returns the contained file with the specified name. /// </summary> /// <param name="filename">File name within the folder.</param> /// <returns>The file within the folder.</returns> public override IClusterResidentObject GetFile(string filename) { this.PopulateCache(); string filepath; if (this.client != null) filepath = this.client.Combine(this.path, filename); else filepath = Path.Combine(this.path, filename); bool isFolder = false; bool isDfsStream = false; long sz = -1; if (blocks.ContainsKey(filepath)) { isDfsStream = true; sz = blocks[filepath]; } else if (pages.ContainsKey(filepath)) { isDfsStream = false; sz = pages[filepath]; } else if (this.client != null) // if the client is null the information may be incorrect isFolder = true; var file = new AzureDfsFile(this.Config, this.Job, this.client, filepath, this.ShouldCacheLocally, isFolder); file.IsDfsStream = isDfsStream; file.size = sz; return file; }
/// <summary> /// If the current object is a folder, it returns the contained objects. /// </summary> /// <returns>An iterator over all contained objects that match the specified string.</returns> /// <param name="match">A shell expression (similar to the argument of Directory.GetFiles()).</param> public override IEnumerable<IClusterResidentObject> GetFilesAndFolders(string match) { this.PopulateCache(); long length = -1; foreach (var child in this.client.EnumerateDirectory(this.path)) { Regex re = Utilities.RegexFromSearchPattern(match); if (!re.IsMatch(child)) continue; bool isFolder = false; bool isDfsStream = false; if (blocks.ContainsKey(child)) { isDfsStream = true; length = blocks[child]; } else if (pages.ContainsKey(child)) { isDfsStream = false; length = pages[child]; } else if (this.client != null) // otherwise this information may be incorrect isFolder = true; var file = new AzureDfsFile(this.Config, this.Job, this.client, child, this.ShouldCacheLocally, isFolder); file.IsDfsStream = isDfsStream; file.size = length; yield return file; } }
/// <summary> /// For a folder object, returns the contained file with the specified name. /// </summary> /// <param name="filename">File name within the folder.</param> /// <returns>The file within the folder.</returns> public override IClusterResidentObject GetFile(string filename) { this.PopulateCache(); string combined = Path.Combine(this.path, filename); Uri filepath = UriFromPath(this.Config as AzureDfsClusterConfiguration, combined); bool isFolder = false; bool isDfsStream = false; long sz = -1; if (this.blocks.ContainsKey(combined)) { isDfsStream = true; sz = this.blocks[filepath.AbsolutePath]; } else if (this.pages.ContainsKey(combined)) { isDfsStream = false; sz = this.pages[filepath.AbsolutePath]; } var file = new AzureDfsFile(this.Config, this.Job, this.client, combined, this.ShouldCacheLocally, isFolder); file.IsDfsStream = isDfsStream; file.size = sz; return file; }
/// <summary> /// If the current object is a folder, it returns the contained objects. /// </summary> /// <returns>An iterator over all contained objects that match the specified string.</returns> /// <param name="match">A shell expression (similar to the argument of Directory.GetFiles()).</param> public override IEnumerable<IClusterResidentObject> GetFilesAndFolders(string match) { this.PopulateCache(); long length = -1; Uri uri = UriFromPath(this.Config as AzureDfsClusterConfiguration, this.path); Console.WriteLine("AzureDfsFile.GetFileAndFolders({0}) -> {1}", this.path, uri); foreach (var child in this.client.ExpandFileOrDirectory(uri)) { Regex re = Utilities.RegexFromSearchPattern(match); if (!re.IsMatch(child.AbsolutePath)) continue; bool isFolder = false; bool isDfsStream = false; if (this.blocks.ContainsKey(child.AbsolutePath)) { isDfsStream = true; length = this.blocks[child.AbsolutePath]; } else if (this.pages.ContainsKey(child.AbsolutePath)) { isDfsStream = false; length = this.pages[child.AbsolutePath]; } var file = new AzureDfsFile(this.Config, this.Job, this.client, PathFromUri(this.Config as AzureDfsClusterConfiguration, child), this.ShouldCacheLocally, isFolder); file.IsDfsStream = isDfsStream; file.size = length; yield return file; } }
/// <summary> /// The directory where a specific process is created on the cluster. /// </summary> /// <param name="identifier">Process identifier</param> /// <param name="machine">Machine where process ran.</param> /// <returns>Home directory containing the process information (not working directory of vertex).</returns> /// <param name="job">Job where the process belongs.</param> /// <param name="terminated">True if vertex is terminated.</param> public override IClusterResidentObject ProcessDirectory(DryadProcessIdentifier identifier, bool terminated, string machine, DryadLinqJobSummary job) { if (identifier.ToString() == "jm") { // The job manager process is special var result = new AzureDfsFile(this, job, this.AzureClient, job.ClusterJobId, terminated, true); return result; } // vertices not supported return null; }