Skip to content

Commit 3a729be

Browse files
committed
Fix measuring time during work item migration
1 parent f69105c commit 3a729be

File tree

1 file changed

+40
-11
lines changed

1 file changed

+40
-11
lines changed

src/MigrationTools.Clients.TfsObjectModel/Processors/TfsWorkItemMigrationProcessor.cs

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,35 @@ namespace MigrationTools.Processors
3737
/// <processingtarget>Work Items</processingtarget>
3838
public class TfsWorkItemMigrationProcessor : TfsProcessor
3939
{
40+
private class ProgressTimer
41+
{
42+
private TimeSpan _totalProcessedTime = TimeSpan.Zero;
43+
44+
public ProgressTimer(int totalCount)
45+
{
46+
TotalCount = totalCount;
47+
}
48+
49+
public int TotalCount { get; private set; }
50+
public int ProcessedCount { get; private set; }
51+
public TimeSpan TotalProcessedTime => _totalProcessedTime;
52+
53+
public void AddProcessedItem(TimeSpan processDuration, bool addToTotal)
54+
{
55+
if (addToTotal)
56+
{
57+
TotalCount++;
58+
}
59+
ProcessedCount++;
60+
_totalProcessedTime += processDuration;
61+
}
62+
63+
public TimeSpan AverageTime => ProcessedCount > 0
64+
? TimeSpan.FromSeconds(TotalProcessedTime.TotalSeconds / ProcessedCount)
65+
: TotalProcessedTime;
66+
67+
public TimeSpan RemainingTime => TimeSpan.FromTicks(AverageTime.Ticks * (TotalCount - ProcessedCount));
68+
}
4069

4170
private static int _count = 0;
4271
private static int _current = 0;
@@ -147,6 +176,8 @@ protected override void InternalExecute()
147176
_current = 1;
148177
_count = sourceWorkItems.Count;
149178
_totalWorkItem = sourceWorkItems.Count;
179+
ProgressTimer progressTimer = new ProgressTimer(_totalWorkItem);
180+
150181
ProcessorActivity.SetTag("source_workitems_to_process", sourceWorkItems.Count);
151182
foreach (WorkItemData sourceWorkItemData in sourceWorkItems)
152183
{
@@ -163,7 +194,7 @@ protected override void InternalExecute()
163194
{
164195
try
165196
{
166-
ProcessWorkItemAsync(sourceWorkItemData, Options.WorkItemCreateRetryLimit).Wait();
197+
ProcessWorkItemAsync(sourceWorkItemData, progressTimer, Options.WorkItemCreateRetryLimit).Wait();
167198

168199
stopwatch.Stop();
169200
var processingTime = stopwatch.Elapsed.TotalMilliseconds;
@@ -407,7 +438,6 @@ private WorkItemData CreateWorkItem_Shell(ProjectData destProject, WorkItemData
407438
activity?.SetTagsFromOptions(Options);
408439
activity?.SetTag("http.request.method", "GET");
409440
activity?.SetTag("migrationtools.client", "TfsObjectModel");
410-
activity?.SetEndTime(activity.StartTimeUtc.AddSeconds(10));
411441

412442
WorkItem newwit;
413443
if (destProject.ToProject().WorkItemTypes.Contains(destType))
@@ -580,14 +610,13 @@ private void ProcessWorkItemEmbeddedLinks(WorkItemData sourceWorkItem, WorkItemD
580610
}
581611
}
582612

583-
private async Task ProcessWorkItemAsync(WorkItemData sourceWorkItem, int retryLimit = 5, int retries = 0)
613+
private async Task ProcessWorkItemAsync(WorkItemData sourceWorkItem, ProgressTimer progressTimer, int retryLimit = 5, int retries = 0)
584614
{
585615
using (var activity = ActivitySourceProvider.ActivitySource.StartActivity("ProcessWorkItemAsync", ActivityKind.Client))
586616
{
587617
activity?.SetTagsFromOptions(Options);
588618
activity?.SetTag("http.request.method", "GET");
589619
activity?.SetTag("migrationtools.client", "TfsObjectModel");
590-
activity?.SetEndTime(activity.StartTimeUtc.AddSeconds(10));
591620
activity?.SetTag("SourceURL", Source.Options.Collection.ToString());
592621
activity?.SetTag("SourceWorkItem", sourceWorkItem.Id);
593622
activity?.SetTag("TargetURL", Target.Options.Collection.ToString());
@@ -675,7 +704,7 @@ private async Task ProcessWorkItemAsync(WorkItemData sourceWorkItem, int retryLi
675704
{"Retrys", retries },
676705
{"RetryLimit", retryLimit }
677706
});
678-
await ProcessWorkItemAsync(sourceWorkItem, retryLimit, retries);
707+
await ProcessWorkItemAsync(sourceWorkItem, progressTimer, retryLimit, retries);
679708
}
680709
else
681710
{
@@ -691,15 +720,15 @@ private async Task ProcessWorkItemAsync(WorkItemData sourceWorkItem, int retryLi
691720
Telemetry.TrackException(ex, activity.Tags);
692721
throw ex;
693722
}
694-
var average = new TimeSpan(0, 0, 0, 0, (int)(activity.Duration.TotalMilliseconds / _current));
695-
var remaining = new TimeSpan(0, 0, 0, 0, (int)(average.TotalMilliseconds * _count));
723+
activity?.Stop();
724+
progressTimer.AddProcessedItem(activity.Duration, retries > 0);
696725
TraceWriteLine(LogEventLevel.Information,
697-
"Average time of {average:%s}.{average:%fff} per work item and {remaining:%h} hours {remaining:%m} minutes {remaining:%s}.{remaining:%fff} seconds estimated to completion",
726+
"Average time of {average:%s}.{average:%fff} per work item and {remaining:%h} hours {remaining:%m} minutes {remaining:%s} seconds estimated to completion.",
698727
new Dictionary<string, object>() {
699-
{"average", average},
700-
{"remaining", remaining}
728+
{ "average", progressTimer.AverageTime },
729+
{ "remaining", progressTimer.RemainingTime }
701730
});
702-
activity?.Stop();
731+
703732
activity?.SetStatus(ActivityStatusCode.Error);
704733
activity?.SetTag("http.response.status_code", "200");
705734

0 commit comments

Comments
 (0)