/// <summary> /// Scan the JM stdout looking for the specified vertex; display the lines in the file view. /// Run in the background. /// </summary> /// <param name="vertex">Vertex to look for.</param> /// <returns>true if the information was found.</returns> /// <param name="logViewer">Viewer to use to display the logs.</param> /// <param name="stdout">Job standard output stream.</param> private static bool ScanJMStdout(ExecutedVertexInstance vertex, IClusterResidentObject stdout, LogViewer logViewer) { if (vertex == null || vertex.IsManager) return false; string vertexId = vertex.UniqueID; string name = string.Format(@"\s{0}.{1}\s", vertex.Number, vertex.Version); // the dot could match a space too. string regexstring = string.Format(@"vertex\s{0}\s(.*)\sv.{1}\s|", vertex.Number, vertex.Version); if (vertexId != "") regexstring += vertexId + "|"; regexstring += name + "|" + vertex.UniqueID; Regex regex = new Regex(regexstring, RegexOptions.Compiled); Trace.TraceInformation(regex.ToString()); long length = stdout.Size; logViewer.Status("Looking for " + vertex.Name, StatusKind.LongOp); if (length == 0) { logViewer.Status("JM stdout is empty.", StatusKind.Error); logViewer.Done(); return false; } ISharedStreamReader sr = stdout.GetStream(); if (sr.Exception != null) { logViewer.Status("Error opening JM stdout: " + sr.Exception.Message, StatusKind.Error); logViewer.Done(); return false; } try { long read = 0; long lines = 0; while (!sr.EndOfStream) { string line = sr.ReadLine(); read += line.Length; if (regex.IsMatch(line)) logViewer.AddLine(stdout.ToString(), lines, line); lines++; if (lines % 100 == 0 && length > 0) { if (logViewer.Cancelled) break; logViewer.UpdateProgress(Math.Min((int)(read * 100 / length), 100)); // the length can grow while the file is being read } } sr.Close(); } finally { logViewer.Done(); } return true; }
/// <summary> /// Get the contents of a specified cluster resident object. /// </summary> /// <param name="path">Cluster object whose contents is read.</param> /// <param name="pattern">Pattern to filter contents, for folders.</param> /// <returns>The file contents.</returns> /// <param name="manager">Communication manager.</param> private static FileContents GetContents(CommManager manager, IClusterResidentObject path, string pattern) { if (path == null) { return new FileContents("Null path"); } StringBuilder output = new StringBuilder(); Dictionary<string, IClusterResidentObject> linkCache = new Dictionary<string, IClusterResidentObject>(); linkCache.Add(path.ToString(), path); string error = (path.RepresentsAFolder ? "Folder " : "") + path; if (path.Exception != null) { error += " [Error accessing: " + path.Exception.Message + "]"; return new FileContents(error); } if (path.RepresentsAFolder) { IEnumerable<IClusterResidentObject> dirs = path.GetFilesAndFolders(pattern); int displayed = 0; foreach (IClusterResidentObject d in dirs) { manager.Token.ThrowIfCancellationRequested(); if (d.Exception != null) { error += " [Error " + d.Exception.Message + "]"; return new FileContents(error); } if (d.RepresentsAFolder) { string dirdisplay = string.Format("{0:u} {1,16} file://{2}", d.CreationTime, "d", d.Name); output.AppendLine(dirdisplay); } else { string filedisplay = string.Format("{0:u} {1,16:N0} file://{2}", d.CreationTime, d.Size, d.Name); output.AppendLine(filedisplay); } linkCache.Add("file://" + d.Name, d); displayed++; } if (displayed == 0) error += "[empty]"; return new FileContents(output.ToString(), error, linkCache); } else { manager.Status("Extracting contents of " + path, StatusKind.LongOp); ISharedStreamReader sr = path.GetStream(); if (sr.Exception != null) { error += " [Error " + sr.Exception.Message + "]"; return new FileContents(error); } else { if (path.Size == 0) error += "[empty]"; var contents = sr.ReadToEnd(manager.Token); return new FileContents(contents, error, linkCache); } } }