Skip to content

Commit a65a5c5

Browse files
committed
Progress changes with each poolmember updating the pool with progress changes to keep track of partial item progress
1 parent 1542122 commit a65a5c5

File tree

4 files changed

+17
-65
lines changed

4 files changed

+17
-65
lines changed

src/PSParallel/InvokeParallelCommand.cs

+2-3
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,7 @@ protected override void EndProcessing()
178178
m_progressManager.TotalCount = m_input.Count;
179179
foreach (var i in m_input)
180180
{
181-
var processed = m_powershellPool.ProcessedCount + m_powershellPool.GetPartiallyProcessedCount();
182-
m_progressManager.UpdateCurrentProgressRecord($"Starting processing of {i}", processed);
181+
m_progressManager.UpdateCurrentProgressRecord($"Starting processing of {i}", m_powershellPool.ProcessedCount);
183182
WriteProgress(m_progressManager.ProgressRecord);
184183
while (!m_powershellPool.TryAddInput(ScriptBlock, i))
185184
{
@@ -263,7 +262,7 @@ private void WriteOutputs()
263262
}
264263
if(!NoProgress)
265264
{
266-
m_progressManager.UpdateCurrentProgressRecord(m_powershellPool.ProcessedCount + m_powershellPool.GetPartiallyProcessedCount());
265+
m_progressManager.UpdateCurrentProgressRecord(m_powershellPool.ProcessedCount);
267266
WriteProgress(m_progressManager.ProgressRecord);
268267
}
269268
}

src/PSParallel/PowerShellPoolMember.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,11 @@ private void InformationOnDataAdded(object sender, DataAddedEventArgs dataAddedE
125125

126126
private void ProgressOnDataAdded(object sender, DataAddedEventArgs dataAddedEventArgs)
127127
{
128-
var record = ((PSDataCollection<ProgressRecord>)sender)[dataAddedEventArgs.Index];
128+
var record = ((PSDataCollection<ProgressRecord>)sender)[dataAddedEventArgs.Index];
129+
var change = record.PercentComplete - m_percentComplete;
129130
m_percentComplete = record.PercentComplete;
130131
m_poolStreams.Progress.Add(record);
132+
m_pool.AddProgressChange(change);
131133
}
132134

133135
private void ErrorOnDataAdded(object sender, DataAddedEventArgs dataAddedEventArgs)

src/PSParallel/PowershellPool.cs

+10-21
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@ sealed class PowershellPool : IDisposable
1919
private readonly List<PowerShellPoolMember> m_poolMembers;
2020
private readonly BlockingCollection<PowerShellPoolMember> m_availablePoolMembers = new BlockingCollection<PowerShellPoolMember>(new ConcurrentQueue<PowerShellPoolMember>());
2121
public readonly PowerShellPoolStreams Streams = new PowerShellPoolStreams();
22+
private int m_totalPercentComplete;
2223

23-
public int ProcessedCount => m_processedCount;
24+
public int ProcessedCount => m_processedCount + PartiallyProcessedCount;
25+
26+
private int PartiallyProcessedCount => m_totalPercentComplete / 100;
2427

2528
public PowershellPool(int poolSize, InitialSessionState initialSessionState, CancellationToken cancellationToken)
2629
{
@@ -39,26 +42,6 @@ public PowershellPool(int poolSize, InitialSessionState initialSessionState, Can
3942
m_runspacePool.SetMaxRunspaces(poolSize);
4043
}
4144

42-
public int GetPartiallyProcessedCount()
43-
{
44-
var totalPercentComplete = 0;
45-
var count = m_poolMembers.Count;
46-
for (int i = 0; i < count; ++i)
47-
{
48-
var percentComplete = m_poolMembers[i].PercentComplete;
49-
if (percentComplete < 0)
50-
{
51-
percentComplete = 0;
52-
}
53-
else if(percentComplete > 100)
54-
{
55-
percentComplete = 100;
56-
}
57-
totalPercentComplete += percentComplete;
58-
}
59-
return totalPercentComplete / 100;
60-
}
61-
6245
public bool TryAddInput(ScriptBlock scriptblock,PSObject inputObject)
6346
{
6447
PowerShellPoolMember poolMember;
@@ -126,6 +109,7 @@ public void ReportAvailable(PowerShellPoolMember poolmember)
126109
{
127110
Interlocked.Decrement(ref m_busyCount);
128111
Interlocked.Increment(ref m_processedCount);
112+
Interlocked.Add(ref m_totalPercentComplete, poolmember.PercentComplete);
129113
while (!m_availablePoolMembers.TryAdd(poolmember, 1000, m_cancellationToken))
130114
{
131115
m_cancellationToken.ThrowIfCancellationRequested();
@@ -149,5 +133,10 @@ public void Stop()
149133
}
150134
WaitForAllPowershellCompleted(5000);
151135
}
136+
137+
public void AddProgressChange(int change)
138+
{
139+
Interlocked.Add(ref m_totalPercentComplete, change);
140+
}
152141
}
153142
}

src/PSParallel/ProgressManager.cs

+2-40
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
using System;
2-
using System.Diagnostics;
1+
using System.Diagnostics;
32
using System.Management.Automation;
43

54
namespace PSParallel
65
{
76
class ProgressManager
87
{
98
public int TotalCount { get; set; }
10-
private ProgressRecord m_progressRecord;
9+
private readonly ProgressRecord m_progressRecord;
1110
private readonly Stopwatch m_stopwatch;
1211

1312
public ProgressManager(int activityId, string activity, string statusDescription, int parentActivityId = -1, int totalCount = 0)
@@ -58,41 +57,4 @@ public ProgressRecord Completed()
5857
private int GetPercentComplete(int count) => count*100/TotalCount;
5958
public int ActivityId => m_progressRecord.ActivityId;
6059
}
61-
62-
63-
class ProgressProjector
64-
{
65-
private readonly Stopwatch m_stopWatch;
66-
private int m_percentComplete;
67-
public ProgressProjector()
68-
{
69-
m_stopWatch = new Stopwatch();
70-
m_percentComplete = -1;
71-
}
72-
73-
public void ReportProgress(int percentComplete)
74-
{
75-
if (percentComplete > 100)
76-
{
77-
percentComplete = 100;
78-
}
79-
m_percentComplete = percentComplete;
80-
}
81-
82-
public bool IsValid => m_percentComplete > 0 && m_stopWatch.IsRunning;
83-
public TimeSpan Elapsed => m_stopWatch.Elapsed;
84-
85-
public TimeSpan ProjectedTotalTime => new TimeSpan(Elapsed.Ticks * 100 / m_percentComplete);
86-
87-
public void Start()
88-
{
89-
m_stopWatch.Start();
90-
m_percentComplete = 0;
91-
}
92-
93-
public void Stop()
94-
{
95-
m_stopWatch.Stop();
96-
}
97-
}
9860
}

0 commit comments

Comments
 (0)