Sequential Task should display its subtasks statuts when building (Feature #46)


Added by Olivier Sannier about 6 years ago. Updated about 6 years ago.


Status:Closed Start date:01/04/2012
Priority:Normal Due date:
Assignee:- % Done:

0%

Category:- Spent time: -
Target version:1.7

Description

From JIRA: http://jira.public.thoughtworks.org/browse/CCNET-1919

Right now, when a build is in progress and it uses sequential tasks, the web dashboard shows this :

Running sequential tasks (114 task(s))

And it stays with this for the duration of the subtasks. In my case, this can be very long and it is quite frustrating to have to rely on the server console to see the progress.
This is why I suggest that the sequential task displays the status from its subtasks, maybe like this :

Running sequential tasks (114 task(s)), [89]: TaskDescription

where TaskDescription is the value of the description XML node for the currently running task.

Here is a test project:

<project name="SequentialTest">
<tasks>
<sequential>
<tasks>
<exec>
<description>Sequential Level 1 - Exec task 1</description>
<buildArgs>/c ping -n 10 127.0.0.1</buildArgs>
<executable>cmd.exe</executable>
<successExitCodes>0</successExitCodes>
</exec>
<exec>
<description>Sequential Level 1 - Exec task 2</description>
<buildArgs>/c ping -n 10 127.0.0.1</buildArgs>
<executable>cmd.exe</executable>
<successExitCodes>0</successExitCodes>
</exec>
<sequential>
<tasks>
<exec>
<description>Sequential Level 2 - Exec task 1</description>
<buildArgs>/c ping -n 10 127.0.0.1</buildArgs>
<executable>cmd.exe</executable>
<successExitCodes>0</successExitCodes>
</exec>
<exec>
<description>Sequential Level 2 - Exec task 2</description>
<buildArgs>/c ping -n 10 127.0.0.1</buildArgs>
<executable>cmd.exe</executable>
<successExitCodes>0</successExitCodes>
</exec>
</tasks>
</sequential>
</tasks>
</sequential>
</tasks>
</project>

The exec task basically sits there for 30 seconds so that you have the time to look at the dashboard and see that the description is just the one I mention, missing the description for the subtasks.

I thought about this and because I came to the conclusion that the parallel task should also show its subtasks statuses, I made the following changes.
In the BuildProgressInformation information, I changed the delegate so that it takes and additional object parameter like this:

public delegate void OnStartupInformationUpdatedDelegate(string information, object UserObject);

And I also added a public property for that user object to be set:

public object OnStartupInformationUpdatedUserObject { get; set; }

Then inside DoStartupInformationUpdated, the call to OnStartupInformationUpdated had to be changed to this:

OnStartupInformationUpdated(information, OnStartupInformationUpdatedUserObject);

This way one can give an object to the BuildProgressInformation before the task is started and get it back when the delegate is called. This allowed to change the code inside SequentialTask to this:

#endregion
private class _RunningSubTaskDetails
{
private int _Index;
private IIntegrationResult _ParentResult;
public _RunningSubTaskDetails(int Index, IIntegrationResult ParentResult)
{
_Index = Index;
_ParentResult = ParentResult;
}
public int Index { get { return _Index; } }
public IIntegrationResult ParentResult { get { return _ParentResult; } }
}
private string _getStatusInformation(string runningSubTaskStartupInfo, _RunningSubTaskDetails Details)
{
string Value = !string.IsNullOrEmpty(Description)
? Description
: string.Format("Running sequential tasks ({0} task(s))", Tasks.Length);
if (Details != null)
Value += string.Format(": [{0}] {1}",
Details.Index,
!string.IsNullOrEmpty(runningSubTaskStartupInfo)
? runningSubTaskStartupInfo
: "No information");
return Value;
}
#region Protected methods
#region Execute()
/// <summary>
/// Runs the task, given the specified <see cref="IIntegrationResult"/>, in the specified <see cref="IProject"/>.
/// </summary>
/// <param name="result"></param>
protected override bool Execute(IIntegrationResult result) {
// Initialise the task
var logger = Logger ?? new DefaultLogger();
var numberOfTasks = Tasks.Length;
result.BuildProgressInformation.SignalStartRunTask(_getStatusInformation("", null));
logger.Info("Starting sequential task with {0} sub-task(s)", numberOfTasks);

// Launch each task
var successCount = 0;
var failureCount = 0;
for (var loop = 0; loop < numberOfTasks; loop++) {
var taskName = string.Format("{0} [{1}]", Tasks[loop].GetType().Name, loop);
logger.Debug("Starting task '{0}'", taskName);
try {
// Start the actual task
var taskResult = result.Clone();
taskResult.BuildProgressInformation.OnStartupInformationUpdatedUserObject = new _RunningSubTaskDetails(loop, result);
taskResult.BuildProgressInformation.OnStartupInformationUpdated = SubTaskStartupInformationUpdated;
var task = Tasks[loop];
RunTask(task, taskResult);
result.Merge(taskResult);
}
catch (Exception error) {
// Handle any error details
result.ExceptionResult = error;
result.Status = IntegrationStatus.Failure;
logger.Warning("Task '{0}' failed!", taskName);
}

// Record the results
if (result.Status IntegrationStatus.Success) {
successCount++;
}
else {
failureCount++;
if (!ContinueOnFailure) break;
}
}

// Clean up
this.CancelTasks();
logger.Info("Sequential task completed: {0} successful, {1} failed", successCount, failureCount);
return failureCount 0;
}
#endregion
#endregion

private void SubTaskStartupInformationUpdated(string information, object UserObject)
{
_RunningSubTaskDetails Details = (_RunningSubTaskDetails)UserObject;
Details.ParentResult.BuildProgressInformation.UpdateStartupInformation(_getStatusInformation(information, Details));
}
}

With this, it allows further use in the parallel task (Issue for this is coming)

Hope this helps

Regards
Olivier


History

Updated by Daniel Hommel about 6 years ago

Pull request merged.

  • Status changed from New to Resolved

Updated by Ruben Willems about 6 years ago

  • Target version set to 1.7
  • Status changed from Resolved to Closed

Also available in: Atom PDF