private async void EndPage() { if (_pageWriter != null) { _pageWriter.Flush(); _pageData.Flush(); //The StreamWriter object calls Dispose() on the provided Stream object when StreamWriter.Dispose is called. _pageWriter.Dispose(); _pageWriter = null; _pageData = null; var taskLog = await planHelper.CreateTaskLog(new TaskLog(string.Format(@"logs\{0:D}", jobId)), default(CancellationToken)).ConfigureAwait(false); // Upload the contents using (FileStream fs = File.Open(_dataFileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { await planHelper.AppendLogContentAsync(taskLog.Id, fs, default(CancellationToken)).ConfigureAwait(false); } // Create a new record and only set the Log field var attachmentUpdataRecord = new TimelineRecord { Id = jobId, Log = taskLog }; await planHelper.UpdateTimelineRecordsAsync(timelineId, attachmentUpdataRecord, default(CancellationToken)).ConfigureAwait(false); } }
public void AddFailure(TimelineRecord record, string classification) { var scope = GetScope(record); var failure = new Failure(scope, classification); failures.Add(failure); }
public TimelineBuilder AddRecord(string previousAttemptTimelineId) { int nextId = 1; if (records.Any()) { nextId += records.Max(r => int.Parse(r.Id)); } TimelineRecord record = new TimelineRecord() { Id = nextId.ToString(), Issues = Array.Empty <TimelineIssue>() }; if (string.IsNullOrEmpty(previousAttemptTimelineId)) { record.PreviousAttempts = Array.Empty <TimelineAttempt>(); } else { record.PreviousAttempts = new[] { new TimelineAttempt() { TimelineId = previousAttemptTimelineId } }; } records.Add(record); return(this); }
private async Task CreateTaskTimelineRecordIfRequired(CancellationToken cancellationToken) { if (taskMessage.TaskInstanceId.Equals(Guid.Empty)) { var timelineRecordId = Guid.NewGuid(); var timelineRecord = new TimelineRecord { Id = timelineRecordId, RecordType = "task", Name = taskMessage.TaskInstanceName, Order = 1, StartTime = DateTime.UtcNow, State = TimelineRecordState.Pending, ParentId = taskMessage.JobId, }; var taskClient = GetTaskClient(taskMessage.PlanUri, taskMessage.AuthToken); await taskClient.UpdateTimelineRecordsAsync( taskMessage.ProjectId, taskMessage.HubName, taskMessage.PlanId, taskMessage.TimelineId, new List <TimelineRecord> { timelineRecord }, cancellationToken); this.taskMessage.TaskInstanceId = timelineRecordId; } }
// log an error issue to job level timeline record private async Task LogWorkerProcessUnhandledException(Pipelines.AgentJobRequestMessage message, string errorMessage) { try { var systemConnection = message.Resources.Endpoints.SingleOrDefault(x => string.Equals(x.Name, WellKnownServiceEndpointNames.SystemVssConnection)); ArgUtil.NotNull(systemConnection, nameof(systemConnection)); var jobServer = HostContext.GetService <IJobServer>(); VssCredentials jobServerCredential = VssUtil.GetVssCredential(systemConnection); VssConnection jobConnection = VssUtil.CreateConnection(systemConnection.Url, jobServerCredential); /* Below is the legacy 'OnPremises' code that is currently unused by the runner * ToDo: re-implement code as appropriate once GHES support is added. * // Make sure SystemConnection Url match Config Url base for OnPremises server * if (!message.Variables.ContainsKey(Constants.Variables.System.ServerType) || * string.Equals(message.Variables[Constants.Variables.System.ServerType]?.Value, "OnPremises", StringComparison.OrdinalIgnoreCase)) * { * try * { * Uri result = null; * Uri configUri = new Uri(_runnerSetting.ServerUrl); * if (Uri.TryCreate(new Uri(configUri.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped)), jobServerUrl.PathAndQuery, out result)) * { * //replace the schema and host portion of messageUri with the host from the * //server URI (which was set at config time) * jobServerUrl = result; * } * } * catch (InvalidOperationException ex) * { * //cannot parse the Uri - not a fatal error * Trace.Error(ex); * } * catch (UriFormatException ex) * { * //cannot parse the Uri - not a fatal error * Trace.Error(ex); * } * } */ await jobServer.ConnectAsync(jobConnection); var timeline = await jobServer.GetTimelineAsync(message.Plan.ScopeIdentifier, message.Plan.PlanType, message.Plan.PlanId, message.Timeline.Id, CancellationToken.None); ArgUtil.NotNull(timeline, nameof(timeline)); TimelineRecord jobRecord = timeline.Records.FirstOrDefault(x => x.Id == message.JobId && x.RecordType == "Job"); ArgUtil.NotNull(jobRecord, nameof(jobRecord)); jobRecord.ErrorCount++; jobRecord.Issues.Add(new Issue() { Type = IssueType.Error, Message = errorMessage }); await jobServer.UpdateTimelineRecordsAsync(message.Plan.ScopeIdentifier, message.Plan.PlanType, message.Plan.PlanId, message.Timeline.Id, new TimelineRecord[] { jobRecord }, CancellationToken.None); } catch (Exception ex) { Trace.Error("Fail to report unhandled exception from Runner.Worker process"); Trace.Error(ex); } }
public async Task UpdateTimelineRecordsAsync(Guid timelineId, TimelineRecord attachmentUpdataRecord, CancellationToken cancellationToken) { await taskClient.UpdateTimelineRecordsAsync(this.projectId, this.planType, this.planId, timelineId, new List <TimelineRecord> { attachmentUpdataRecord }, cancellationToken); }
/// <summary> /// Converts a <see cref="TimelineRecord"/> to an <see cref="AzureDevOpsTimelineRecord"/>. /// </summary> /// <param name="timelineRecord">Timeline record to convert.</param> /// <returns>Converted timeline record.</returns> public static AzureDevOpsTimelineRecord ToAzureDevOpsTimelineRecord(this TimelineRecord timelineRecord) { timelineRecord.NotNull(nameof(timelineRecord)); return (new AzureDevOpsTimelineRecord { Attempt = timelineRecord.Attempt, ChangeId = timelineRecord.ChangeId, CurrentOperation = timelineRecord.CurrentOperation, ErrorCount = timelineRecord.ErrorCount, FinishTime = timelineRecord.FinishTime, Id = timelineRecord.Id, LastModified = timelineRecord.LastModified, Name = timelineRecord.Name, Order = timelineRecord.Order, ParentId = timelineRecord.ParentId, PercentComplete = timelineRecord.PercentComplete, RecordType = timelineRecord.RecordType, Result = timelineRecord.Result?.ToAzureDevOpsTaskResult(), ResultCode = timelineRecord.ResultCode, StartTime = timelineRecord.StartTime, State = timelineRecord.State?.ToAzureDevOpsTimelineRecordState(), WarningCount = timelineRecord.WarningCount, WorkerName = timelineRecord.WorkerName, }); }
private async Task EndPage() { if (pageWriter != null) { pageWriter.Flush(); pageData.Flush(); pageWriter.Dispose(); pageWriter = null; pageData = null; var log = new TaskLog(string.Format(@"logs\{0:D}", taskProperties.TaskInstanceId)); var taskLog = await taskClient.CreateLogAsync(log).ConfigureAwait(false); // Upload the contents using (var fs = File.Open(dataFileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { await taskClient.AppendLogContentAsync(taskLog.Id, fs).ConfigureAwait(false); } // Create a new record and only set the Log field var attachmentUpdataRecord = new TimelineRecord { Id = taskProperties.TaskInstanceId, Log = taskLog }; await taskClient.UpdateTimelineRecordsAsync(attachmentUpdataRecord, default(CancellationToken)).ConfigureAwait(false); } }
private string GetScope(TimelineRecord record) { var timelineStack = new Stack <TimelineRecord>(); var current = record; while (true) { timelineStack.Push(current); var parent = Timeline.Records.Where(r => r.Id == current.ParentId).SingleOrDefault(); if (parent == null) { break; } else { current = parent; } } var scopeBuilder = new StringBuilder(); timelineStack.ForEach(r => scopeBuilder.Append($"/{r.RecordType}:{r.Name}")); var scope = scopeBuilder.ToString(); return(scope); }
public void RecordSpeech(string jsonString) { SpeechHistory history = JsonUtility.FromJson <SpeechHistory>(jsonString); TextRecord textRecord = new TextRecord(history.durationSec); VoiceRecord voiceRecord = new VoiceRecord(history.durationSec, history.fileID); TimelineRecord timeline = timelineRecords.Find(t => t.timeSec == history.timeSec); if (timeline == null) { timeline = new TimelineRecord(); timeline.timeSec = history.timeSec; timeline.text = textRecord; timeline.voice = voiceRecord; timelineRecords.Add(timeline); return; } if (timeline.text == null) { timeline.text = textRecord; } if (timeline.voice == null) { timeline.voice = voiceRecord; } else { Utilities.MergeValues(timeline.voice, voiceRecord); } }
public void RecordGraphicSwitching(string showGraphicId, string hideGraphicId) { if (!isRecording) { return; } List <GraphicRecord> graphicRecords = new List <GraphicRecord>(); if (showGraphicId != null) { GraphicRecord record = new GraphicRecord(showGraphicId, "show"); graphicRecords.Add(record); } if (hideGraphicId != null) { GraphicRecord record = new GraphicRecord(hideGraphicId, "hide"); graphicRecords.Add(record); } TimelineRecord timeline = timelineRecords.Find(t => t.timeSec == CurrentTimeSec()); if (timeline == null) { timeline = new TimelineRecord(); timeline.timeSec = CurrentTimeSec(); timelineRecords.Add(timeline); } ; timeline.graphic = graphicRecords; }
public SearchBuildLogsResult(BuildResultInfo buildInfo, string jobName, TimelineRecord record, BuildLogReference buildLogReference, string line) { BuildInfo = buildInfo; JobName = jobName; Record = record; BuildLogReference = buildLogReference; Line = line; }
public TimelineRecordItem( TimelineRecord record, TimelineTree tree) { Debug.Assert(tree.TryGetNode(record.Id, out _)); Record = record; Tree = tree; }
public SearchTimelineResult( Build build, TimelineRecord timelineRecord, string line) { Build = build; TimelineRecord = timelineRecord; Line = line; }
private async Task <int> GetOrCreateTaskLogId(IServiceBusMessage message, CancellationToken cancellationToken, ITaskClient taskClient, Guid projectId, Guid planId, Guid jobId, Guid parentTimelineId, string timelineName, string hubName) { // attempt to get from message var logIdObject = message.GetProperty(VstsMessageConstants.TaskLogIdPropertyName); var taskLogId = 0; var gotLogId = logIdObject != null && int.TryParse(logIdObject.ToString(), out taskLogId); if (gotLogId) { return(taskLogId); } // attempt to find existing var records = await taskClient.GetRecordsAsync(projectId, hubName, planId, parentTimelineId, userState : null, cancellationToken : cancellationToken).ConfigureAwait(false); foreach (var record in records) { if (string.Equals(record.Name, timelineName, StringComparison.OrdinalIgnoreCase)) { return(record.Log.Id); } } // Create a new timeline var subTimelineId = Guid.NewGuid(); // create a log file var logsSubtimelineId = string.Format(@"logs\{0:D}", subTimelineId); var taskLog = await taskClient.CreateLogAsync(projectId, hubName, planId, new TaskLog(logsSubtimelineId), userState : null, cancellationToken : cancellationToken).ConfigureAwait(false); // create a sub-timeline var timelineRecord = new TimelineRecord { Id = subTimelineId, Name = timelineName, StartTime = DateTime.UtcNow, State = TimelineRecordState.InProgress, RecordType = "task", // Record type can be job or task, as we will be dealing only with task here WorkerName = this.settings.WorkerName, Order = 1, // The job timeline record must be at order 1 Log = taskLog, ParentId = jobId, PercentComplete = 0, ErrorCount = 0, WarningCount = 0 }; await taskClient.UpdateTimelineRecordsAsync(projectId, hubName, planId, parentTimelineId, new List <TimelineRecord> { timelineRecord }, cancellationToken).ConfigureAwait(false); // save the taskLogId on the message taskLogId = taskLog.Id; return(taskLogId); }
public Job(TimelineRecord record, int depth) { Depth = depth; Id = record.Id; Name = record.Name; Duration = record.Duration; Order = record.Order; Result = record.Result; LogId = record.Log?.Id; }
public void QueueTimelineRecordUpdate(Guid timelineId, TimelineRecord timelineRecord) { ArgUtil.NotEmpty(timelineId, nameof(timelineId)); ArgUtil.NotNull(timelineRecord, nameof(timelineRecord)); ArgUtil.NotEmpty(timelineRecord.Id, nameof(timelineRecord.Id)); _timelineUpdateQueue.TryAdd(timelineId, new ConcurrentQueue <TimelineRecord>()); Trace.Verbose("Enqueue timeline {0} update queue: {1}", timelineId, timelineRecord.Id); _timelineUpdateQueue[timelineId].Enqueue(timelineRecord.Clone()); }
public bool TryGetParent(TimelineRecord record, [NotNullWhen(true)] out TimelineRecord?parent) { if (IdToNodeMap.TryGetValue(record.Id, out var node) && node.ParentNode is object) { parent = node.ParentNode.TimelineRecord; return(true); } parent = null; return(false); }
private async Task UploadFile(UploadFileInfo file) { bool uploadSucceed = false; try { if (String.Equals(file.Type, CoreAttachmentType.Log, StringComparison.OrdinalIgnoreCase)) { // Create the log var taskLog = await _jobServer.CreateLogAsync(_scopeIdentifier, _hubName, _planId, new TaskLog(String.Format(@"logs\{0:D}", file.TimelineRecordId)), default(CancellationToken)); // Upload the contents using (FileStream fs = File.Open(file.Path, FileMode.Open, FileAccess.Read, FileShare.Read)) { var logUploaded = await _jobServer.AppendLogContentAsync(_scopeIdentifier, _hubName, _planId, taskLog.Id, fs, default(CancellationToken)); } // Create a new record and only set the Log field var attachmentUpdataRecord = new TimelineRecord() { Id = file.TimelineRecordId, Log = taskLog }; QueueTimelineRecordUpdate(file.TimelineId, attachmentUpdataRecord); } else { // Create attachment using (FileStream fs = File.Open(file.Path, FileMode.Open, FileAccess.Read, FileShare.Read)) { var result = await _jobServer.CreateAttachmentAsync(_scopeIdentifier, _hubName, _planId, file.TimelineId, file.TimelineRecordId, file.Type, file.Name, fs, default(CancellationToken)); } } uploadSucceed = true; } finally { if (uploadSucceed && file.DeleteSource) { try { File.Delete(file.Path); } catch (Exception ex) { Trace.Info("Catch exception during delete success uploaded file."); Trace.Error(ex); } } } }
protected IList <string> GetTimelineLogLines(TimelineRecord record) { var jobService = GetMockedService <FakeJobServer>(); var lines = jobService.LogLines.GetValueOrDefault(record.Log.Id).ToList(); if (lines.Count <= 0) { lines = new List <string>(); // Fall back to blobstore foreach (var blobId in jobService.IdToBlobMapping.GetValueOrDefault(record.Log.Id)) { lines.AddRange(jobService.UploadedLogBlobs.GetValueOrDefault(blobId)); } } return(lines); }
public void RecordFacialExpression(string expressionName) { float currentTime = CurrentTimeSec(); TimelineRecord timeline = timelineRecords.Find(t => t.timeSec == currentTime); if (timeline == null) { timeline = new TimelineRecord(); timeline.timeSec = currentTime; timelineRecords.Add(timeline); } ; SpecialActionRecord action = new SpecialActionRecord(null, expressionName); timeline.spAction = action; }
private async Task <JobTestTime> TryGetJobTestTime(TimelineRecord record, TimelineRecord parentRecord) { using var stream = new MemoryStream(); await DevOpsServer.DownloadFileAsync(record.Log.Url, stream); stream.Position = 0; var totalTimeRegex = new Regex(@"Test execution time: ([\d.:]+)", RegexOptions.IgnoreCase | RegexOptions.Compiled); var assemblyTimeRegex = new Regex(@" ([\w.]+\.dll[\d.]*)\s+PASSED ([\d.:]+)", RegexOptions.IgnoreCase | RegexOptions.Compiled); var jobName = parentRecord.Name; var assemblies = new List <AssemblyTestTime>(); TimeSpan?jobDuration = null; using var reader = new StreamReader(stream); do { var line = await reader.ReadLineAsync(); if (line is null) { break; } var assemblyTimeMatch = assemblyTimeRegex.Match(line); if (assemblyTimeMatch.Success) { var duration = TimeSpan.Parse(assemblyTimeMatch.Groups[2].Value); assemblies.Add(new AssemblyTestTime(assemblyTimeMatch.Groups[1].Value, duration)); continue; } var totalTimeMatch = totalTimeRegex.Match(line); if (totalTimeMatch.Success) { jobDuration = TimeSpan.Parse(totalTimeMatch.Groups[1].Value); break; } } while (true); return(jobDuration is object ?new JobTestTime(jobName, jobDuration.Value, assemblies) : null); }
public void UpdateDetailTimelineRecord(TimelineRecord record) { ArgUtil.NotNull(record, nameof(record)); if (record.RecordType == ExecutionContextType.Job) { throw new ArgumentOutOfRangeException(nameof(record)); } if (_detailTimelineId == Guid.Empty) { // create detail timeline _detailTimelineId = Guid.NewGuid(); _record.Details = new Timeline(_detailTimelineId); _jobServerQueue.QueueTimelineRecordUpdate(_mainTimelineId, _record); } TimelineRecord existRecord; if (_detailRecords.TryGetValue(record.Id, out existRecord)) { existRecord.Name = record.Name ?? existRecord.Name; existRecord.RecordType = record.RecordType ?? existRecord.RecordType; existRecord.Order = record.Order ?? existRecord.Order; existRecord.ParentId = record.ParentId ?? existRecord.ParentId; existRecord.StartTime = record.StartTime ?? existRecord.StartTime; existRecord.FinishTime = record.FinishTime ?? existRecord.FinishTime; existRecord.PercentComplete = record.PercentComplete ?? existRecord.PercentComplete; existRecord.CurrentOperation = record.CurrentOperation ?? existRecord.CurrentOperation; existRecord.Result = record.Result ?? existRecord.Result; existRecord.ResultCode = record.ResultCode ?? existRecord.ResultCode; existRecord.State = record.State ?? existRecord.State; _jobServerQueue.QueueTimelineRecordUpdate(_detailTimelineId, existRecord); } else { _detailRecords[record.Id] = record; _jobServerQueue.QueueTimelineRecordUpdate(_detailTimelineId, record); } }
public GateHelper(string taskInstanceId, string hubName, string jobId, string planId, string timelineId, string projectId, string vstsUrl, string authToken) { // create guuids this.JobGuid = new Guid(jobId); this.PlanGuid = new Guid(planId); this.TimelineGuid = new Guid(timelineId); this.ProjectGuid = new Guid(projectId); this.TaskInstanceGuid = new Guid(taskInstanceId); // save token and vsts url this.VstsUrl = vstsUrl; this.AuthToken = authToken; this.HubName = hubName; // create connection to vsts try { this.Connection = new VssConnection(new Uri(this.VstsUrl), new VssBasicCredential("", authToken)); } catch (Exception e) { System.Console.WriteLine("ok"); } // get task client try { this.TaskClient = this.Connection.GetClient <TaskHttpClient>(); } catch (Exception e) { System.Console.WriteLine("ok"); } // get the plan this.Plan = this.TaskClient.GetPlanAsync(this.ProjectGuid, this.HubName, this.PlanGuid).SyncResult(); // get httpTaskTimeLineRecord var timeLineRecords = this.TaskClient.GetRecordsAsync(this.ProjectGuid, this.HubName, this.PlanGuid, this.TimelineGuid).SyncResult(); this.TimelineRecord = timeLineRecords.Where(record => record.ParentId != null) .First(); }
private async Task CreateTaskTimelineRecordIfRequired(TaskClient taskClient, CancellationToken cancellationToken) { if (taskProperties.TaskInstanceId.Equals(Guid.Empty)) { taskProperties.TaskInstanceId = Guid.NewGuid(); } var timelineRecord = new TimelineRecord { Id = taskProperties.TaskInstanceId, RecordType = "task", Name = taskProperties.TaskInstanceName, Order = 1, StartTime = DateTime.UtcNow, State = TimelineRecordState.Pending, ParentId = taskProperties.JobId, }; // this is an upsert call await taskClient.UpdateTimelineRecordsAsync(timelineRecord, cancellationToken).ConfigureAwait(false); }
private void MergeTimelineRecords(TimelineRecord timelineRecord, TimelineRecord rec) { timelineRecord.CurrentOperation = rec.CurrentOperation ?? timelineRecord.CurrentOperation; timelineRecord.Details = rec.Details ?? timelineRecord.Details; timelineRecord.FinishTime = rec.FinishTime ?? timelineRecord.FinishTime; timelineRecord.Log = rec.Log ?? timelineRecord.Log; timelineRecord.Name = rec.Name ?? timelineRecord.Name; timelineRecord.RefName = rec.RefName ?? timelineRecord.RefName; timelineRecord.PercentComplete = rec.PercentComplete ?? timelineRecord.PercentComplete; timelineRecord.RecordType = rec.RecordType ?? timelineRecord.RecordType; timelineRecord.Result = rec.Result ?? timelineRecord.Result; timelineRecord.ResultCode = rec.ResultCode ?? timelineRecord.ResultCode; timelineRecord.StartTime = rec.StartTime ?? timelineRecord.StartTime; timelineRecord.State = rec.State ?? timelineRecord.State; timelineRecord.WorkerName = rec.WorkerName ?? timelineRecord.WorkerName; if (rec.ErrorCount != null && rec.ErrorCount > 0) { timelineRecord.ErrorCount = rec.ErrorCount; } if (rec.WarningCount != null && rec.WarningCount > 0) { timelineRecord.WarningCount = rec.WarningCount; } if (rec.Issues.Count > 0) { timelineRecord.Issues.Clear(); timelineRecord.Issues.AddRange(rec.Issues.Select(i => i.Clone())); } if (rec.Variables.Count > 0) { foreach (var variable in rec.Variables) { timelineRecord.Variables[variable.Key] = variable.Value.Clone(); } } }
public async Task CreateTaskTimelineRecordIfRequired(TaskClient taskClient, CancellationToken cancellationToken) { if (taskProperties.TaskInstanceId.Equals(Guid.Empty)) { taskProperties.TaskInstanceId = Guid.NewGuid(); } var timelineRecord = new TimelineRecord { Id = taskProperties.TaskInstanceId, RecordType = "task", StartTime = DateTime.UtcNow, ParentId = taskProperties.JobId, }; if (!string.IsNullOrWhiteSpace(taskProperties.TaskInstanceName)) { timelineRecord.Name = taskProperties.TaskInstanceName; } // this is an upsert call await taskClient.UpdateTimelineRecordAsync(timelineRecord, cancellationToken).ConfigureAwait(false); }
private void timelineLV_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (sender == null) { return; } ListView lv = sender as ListView; if (lv == null) { return; } TimelineRecord tr = lv.SelectedItem as TimelineRecord; if (tr != null && !String.IsNullOrWhiteSpace(tr.LogUrl) && tr.ParentId != null) { Frame.Navigate(typeof(LogPage), new StringKeyValuePair { key = tr.Name, value = tr.LogUrl }); } }
private async Task UploadFile(UploadFileInfo file) { bool uploadSucceed = false; try { if (String.Equals(file.Type, CoreAttachmentType.Log, StringComparison.OrdinalIgnoreCase)) { // Create the log var taskLog = await _jobServer.CreateLogAsync(_scopeIdentifier, _hubName, _planId, new TaskLog(String.Format(@"logs\{0:D}", file.TimelineRecordId)), default(CancellationToken)); using (FileStream fs = File.Open(file.Path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { if (_writeToBlobStoreLogs) { try { var blobBlockId = await _jobServer.UploadLogToBlobStore(fs, _hubName, _planId, taskLog.Id); int lineCount = File.ReadLines(file.Path).Count(); // Notify TFS await _jobServer.AssociateLogAsync(_scopeIdentifier, _hubName, _planId, taskLog.Id, blobBlockId, lineCount, default(CancellationToken)); } catch { // Fall back to FCS fs.Position = 0; await _jobServer.AppendLogContentAsync(_scopeIdentifier, _hubName, _planId, taskLog.Id, fs, default(CancellationToken)); } } else { await _jobServer.AppendLogContentAsync(_scopeIdentifier, _hubName, _planId, taskLog.Id, fs, default(CancellationToken)); } } // Create a new record and only set the Log field var attachmentUpdataRecord = new TimelineRecord() { Id = file.TimelineRecordId, Log = taskLog }; QueueTimelineRecordUpdate(file.TimelineId, attachmentUpdataRecord); } else { if (_writeToBlobStoreAttachments) { try { var(dedupId, length) = await _jobServer.UploadAttachmentToBlobStore(_debugMode, file.Path, _planId, _jobTimelineRecordId, default(CancellationToken)); // Notify TFS await _jobServer.AssosciateAttachmentAsync(_scopeIdentifier, _hubName, _planId, file.TimelineId, file.TimelineRecordId, file.Type, file.Name, dedupId, (long)length, default(CancellationToken)); } catch { // Fall back to file-based FCS using (FileStream fs = File.Open(file.Path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { var result = await _jobServer.CreateAttachmentAsync(_scopeIdentifier, _hubName, _planId, file.TimelineId, file.TimelineRecordId, file.Type, file.Name, fs, default(CancellationToken)); } } } else { // Create attachment using (FileStream fs = File.Open(file.Path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { var result = await _jobServer.CreateAttachmentAsync(_scopeIdentifier, _hubName, _planId, file.TimelineId, file.TimelineRecordId, file.Type, file.Name, fs, default(CancellationToken)); } } } uploadSucceed = true; } finally { if (uploadSucceed && file.DeleteSource) { try { File.Delete(file.Path); } catch (Exception ex) { Trace.Info("Catch exception during delete success uploaded file."); Trace.Error(ex); } } } }
private async Task UploadFile(UploadFileInfo file) { bool uploadSucceed = false; try { if (String.Equals(file.Type, CoreAttachmentType.Log, StringComparison.OrdinalIgnoreCase)) { // Create the log var taskLog = await _jobServer.CreateLogAsync(_scopeIdentifier, _hubName, _planId, new TaskLog(String.Format(@"logs\{0:D}", file.TimelineRecordId)), default(CancellationToken)); // Upload the contents using (FileStream fs = File.OpenRead(file.Path)) { var logUploaded = await _jobServer.AppendLogContentAsync(_scopeIdentifier, _hubName, _planId, taskLog.Id, fs, default(CancellationToken)); } // Create a new record and only set the Log field var attachmentUpdataRecord = new TimelineRecord() { Id = file.TimelineRecordId, Log = taskLog }; QueueTimelineRecordUpdate(file.TimelineId, attachmentUpdataRecord); } else { // Create attachment using (FileStream fs = File.OpenRead(file.Path)) { var result = await _jobServer.CreateAttachmentAsync(_scopeIdentifier, _hubName, _planId, file.TimelineId, file.TimelineRecordId, file.Type, file.Name, fs, default(CancellationToken)); } } uploadSucceed = true; } finally { if (uploadSucceed && file.DeleteSource) { try { File.Delete(file.Path); } catch (Exception ex) { Trace.Info("Catch exception during delete success uploaded file."); Trace.Error(ex); } } } }
public void QueueTimelineRecordUpdate(Guid timelineId, TimelineRecord timelineRecord) { ArgUtil.NotEmpty(timelineId, nameof(timelineId)); ArgUtil.NotNull(timelineRecord, nameof(timelineRecord)); ArgUtil.NotEmpty(timelineRecord.Id, nameof(timelineRecord.Id)); _timelineUpdateQueue.TryAdd(timelineId, new ConcurrentQueue<TimelineRecord>()); Trace.Verbose("Enqueue timeline {0} update queue: {1}", timelineId, timelineRecord.Id); _timelineUpdateQueue[timelineId].Enqueue(timelineRecord.Clone()); }
public async Task UpdateTimelineRecordsAsync(TimelineRecord timelineRecord, CancellationToken cancellationToken) { await taskClient.UpdateTimelineRecordsAsync(this.taskProperties.ProjectId, this.taskProperties.HubName, this.taskProperties.PlanId, this.taskProperties.TimelineId, new List <TimelineRecord> { timelineRecord }, cancellationToken).ConfigureAwait(false); }
private void ProcessTaskDetailCommand(IExecutionContext context, Dictionary<string, string> eventProperties, string data) { TimelineRecord record = new TimelineRecord(); String timelineRecord; if (!eventProperties.TryGetValue(TaskDetailEventProperties.TimelineRecordId, out timelineRecord) || string.IsNullOrEmpty(timelineRecord) || new Guid(timelineRecord).Equals(Guid.Empty)) { throw new Exception(StringUtil.Loc("MissingTimelineRecordId")); } else { record.Id = new Guid(timelineRecord); } string parentTimlineRecord; if (eventProperties.TryGetValue(TaskDetailEventProperties.ParentTimelineRecordId, out parentTimlineRecord)) { record.ParentId = new Guid(parentTimlineRecord); } String name; if (eventProperties.TryGetValue(TaskDetailEventProperties.Name, out name)) { record.Name = name; } String recordType; if (eventProperties.TryGetValue(TaskDetailEventProperties.Type, out recordType)) { record.RecordType = recordType; } String order; if (eventProperties.TryGetValue(TaskDetailEventProperties.Order, out order)) { int orderInt = 0; if (int.TryParse(order, out orderInt)) { record.Order = orderInt; } } String percentCompleteValue; if (eventProperties.TryGetValue(TaskDetailEventProperties.Progress, out percentCompleteValue)) { Int32 progress; if (Int32.TryParse(percentCompleteValue, out progress)) { record.PercentComplete = (Int32)Math.Min(Math.Max(progress, 0), 100); } } if (!String.IsNullOrEmpty(data)) { record.CurrentOperation = data; } string result; if (eventProperties.TryGetValue(TaskDetailEventProperties.Result, out result)) { record.Result = EnumUtil.TryParse<TaskResult>(result) ?? TaskResult.Succeeded; } String startTime; if (eventProperties.TryGetValue(TaskDetailEventProperties.StartTime, out startTime)) { record.StartTime = ParseDateTime(startTime, DateTime.UtcNow); } String finishtime; if (eventProperties.TryGetValue(TaskDetailEventProperties.FinishTime, out finishtime)) { record.FinishTime = ParseDateTime(finishtime, DateTime.UtcNow); } String state; if (eventProperties.TryGetValue(TaskDetailEventProperties.State, out state)) { record.State = ParseTimelineRecordState(state, TimelineRecordState.Pending); } TimelineRecord trackingRecord; // in front validation as much as possible. // timeline record is happened in back end queue, user will not receive result of the timeline record updates. // front validation will provide user better understanding when things went wrong. if (_timelineRecordsTracker.TryGetValue(record.Id, out trackingRecord)) { // we already created this timeline record // make sure parentid does not changed. if (record.ParentId != null && record.ParentId != trackingRecord.ParentId) { throw new Exception(StringUtil.Loc("CannotChangeParentTimelineRecord")); } else if (record.ParentId == null) { record.ParentId = trackingRecord.ParentId; } // populate default value for empty field. if (record.State == TimelineRecordState.Completed) { if (record.PercentComplete == null) { record.PercentComplete = 100; } if (record.FinishTime == null) { record.FinishTime = DateTime.UtcNow; } } } else { // we haven't created this timeline record // make sure we have name/type and parent record has created. if (string.IsNullOrEmpty(record.Name)) { throw new Exception(StringUtil.Loc("NameRequiredForTimelineRecord")); } if (string.IsNullOrEmpty(record.RecordType)) { throw new Exception(StringUtil.Loc("TypeRequiredForTimelineRecord")); } if (record.ParentId != null && record.ParentId != Guid.Empty) { if (!_timelineRecordsTracker.ContainsKey(record.ParentId.Value)) { throw new Exception(StringUtil.Loc("ParentTimelineNotCreated")); } } // populate default value for empty field. if (record.StartTime == null) { record.StartTime = DateTime.UtcNow; } if (record.State == null) { record.State = TimelineRecordState.InProgress; } } context.UpdateDetailTimelineRecord(record); _timelineRecordsTracker[record.Id] = record; }
public int AddAbsolute(float time, Action action, string comment = null) { var record = new TimelineRecord { Time = time, Action = action, Comment = comment, RecordId = _MaxRecordId++ }; if (_Current == null || _Current.Time > time) _Current = record; for (var idx = 0; idx < _KeyFrames.Count; idx++) { var curr = _KeyFrames[idx]; if (curr.Time > time) { _KeyFrames.Insert(idx, record); return record.RecordId; } } // the current item is the last _KeyFrames.Add(record); return record.RecordId; }
private void shiftCurrent() { var nextIndex = _KeyFrames.IndexOf(_Current) + 1; if (nextIndex < _KeyFrames.Count) { _Current = _KeyFrames[nextIndex]; if (nextIndex > SKIPPED_EVENT_THRESHOLD && !IsLooped) clearSkipped(); } else { if (IsLooped) { CurrentTime = 0; _Current = _KeyFrames[0]; } else { _Current = null; } } }