Skip to content

Commit c0d7f43

Browse files
authored
Merge pull request Azure#5086 from markcowl/asjobparamset
Fix jobs when used with cmdlets that require parametersetname
2 parents 2f2718d + c1b2d78 commit c0d7f43

File tree

3 files changed

+236
-88
lines changed

3 files changed

+236
-88
lines changed

src/Common/Commands.Common/AzureLongRunningJob.cs

Lines changed: 72 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,59 @@
2626

2727
namespace Microsoft.Azure.Commands.Common
2828
{
29-
public class AzureLongRunningJob<T> : Job, ICommandRuntime where T : AzurePSCmdlet
29+
/// <summary>
30+
/// Abstract class for uniform processing of jobs
31+
/// </summary>
32+
public abstract class AzureLongRunningJob : Job
33+
{
34+
protected AzureLongRunningJob(string command, string name) : base(command, name)
35+
{
36+
}
37+
38+
/// <summary>
39+
/// Run a cmdlet execution as a Job - this is intended to run in a background thread
40+
/// </summary>
41+
/// <param name="state">The Job record that will track the progress of this job </param>
42+
public abstract void RunJob(object state);
43+
44+
/// <summary>
45+
/// Return cmdlet runtime that will report results to this job
46+
/// </summary>
47+
/// <returns>An IcommandRuntime that reports results to this job</returns>
48+
public abstract ICommandRuntime GetJobRuntime();
49+
50+
/// <summary>
51+
/// Mark the job as started
52+
/// </summary>
53+
public abstract bool TryStart();
54+
55+
/// <summary>
56+
/// Mark the job as Blocked
57+
/// </summary>
58+
public abstract bool TryBlock();
59+
60+
61+
/// <summary>
62+
/// Complete the job (will mark job as Completed or Failed, depending on the execution details)
63+
/// </summary>
64+
public abstract void Complete();
65+
66+
/// <summary>
67+
/// Mark the Job as Failed
68+
/// </summary>
69+
public abstract void Fail();
70+
71+
/// <summary>
72+
/// Stop the job
73+
/// </summary>
74+
public abstract void Cancel();
75+
}
76+
77+
/// <summary>
78+
/// Cmdlet-specific Implementation class for long running jobs
79+
/// </summary>
80+
/// <typeparam name="T">The type of the cmdlet being executed</typeparam>
81+
public class AzureLongRunningJob<T> : AzureLongRunningJob, ICommandRuntime where T : AzurePSCmdlet
3082
{
3183
string _status = "Running";
3284
T _cmdlet;
@@ -196,14 +248,15 @@ public static U CopyCmdlet<U>(U cmdlet) where U : AzurePSCmdlet
196248
field.SafeCopyValue(source: cmdlet, target: returnValue);
197249
}
198250

251+
cmdlet.SafeCopyParameterSet(returnValue);
199252
return returnValue as U;
200253
}
201254

202255
/// <summary>
203256
/// Run a cmdlet execution as a Job - this is intended to run in a background thread
204257
/// </summary>
205258
/// <param name="state">The Job record that will track the progress of this job </param>
206-
public virtual void RunJob(object state)
259+
public override void RunJob(object state)
207260
{
208261
if (TryStart())
209262
{
@@ -239,7 +292,7 @@ public virtual void RunJob(object state)
239292
/// Return cmdlet runtime that will report results to this job
240293
/// </summary>
241294
/// <returns>An IcommandRuntime that reports results to this job</returns>
242-
public virtual ICommandRuntime GetJobRuntime()
295+
public override ICommandRuntime GetJobRuntime()
243296
{
244297
return this as ICommandRuntime;
245298
}
@@ -307,7 +360,7 @@ internal string GetShouldMethodFailureReaon(T cmdlet, ShouldMethodStreamItem met
307360
/// <summary>
308361
/// Mark the task as started
309362
/// </summary>
310-
public bool TryStart()
363+
public override bool TryStart()
311364
{
312365
bool result = false;
313366
lock (_lockObject)
@@ -326,7 +379,7 @@ public bool TryStart()
326379
/// <summary>
327380
/// Mark the task as blocked
328381
/// </summary>
329-
public bool TryBlock()
382+
public override bool TryBlock()
330383
{
331384
bool result = false;
332385
lock (_lockObject)
@@ -345,7 +398,7 @@ public bool TryBlock()
345398
/// <summary>
346399
/// Mark the job as Failed
347400
/// </summary>
348-
public void Fail()
401+
public override void Fail()
349402
{
350403
lock (_lockObject)
351404
{
@@ -357,7 +410,7 @@ public void Fail()
357410
/// <summary>
358411
/// Mark the job as successfully complete
359412
/// </summary>
360-
public void Complete()
413+
public override void Complete()
361414
{
362415
lock (_lockObject)
363416
{
@@ -378,7 +431,7 @@ public void Complete()
378431
/// <summary>
379432
/// Mark the job as cancelled
380433
/// </summary>
381-
public void Cancel()
434+
public override void Cancel()
382435
{
383436
lock (_lockObject)
384437
{
@@ -787,8 +840,7 @@ private bool InvokeShouldMethodAndWaitForResults(Func<Cmdlet, bool> shouldMethod
787840
try
788841
{
789842
stateChangedEventHandler(null, new JobStateEventArgs(this.JobStateInfo));
790-
791-
if (!gotResultEvent.IsSet && this.TryBlock())
843+
if (!gotResultEvent.IsSet)
792844
{
793845
WriteDebug(string.Format(Resources.TraceBlockLROThread, methodType));
794846
ShouldMethodInvoker methodInvoker = new ShouldMethodInvoker
@@ -800,16 +852,18 @@ private bool InvokeShouldMethodAndWaitForResults(Func<Cmdlet, bool> shouldMethod
800852
};
801853

802854
BlockedActions.Enqueue(new ShouldMethodStreamItem(methodInvoker));
803-
804-
gotResultEvent.Wait();
805-
WriteDebug(string.Format(Resources.TraceUnblockLROThread, shouldMethod));
806-
TryStart();
807-
lock (resultsLock)
855+
if (this.TryBlock())
808856
{
809-
if (closureSafeExceptionThrownOnCmdletThread == null) // stateChangedEventHandler didn't set the results? = ok to clobber results?
857+
gotResultEvent.Wait();
858+
WriteDebug(string.Format(Resources.TraceUnblockLROThread, shouldMethod));
859+
TryStart();
860+
lock (resultsLock)
810861
{
811-
closureSafeExceptionThrownOnCmdletThread = methodInvoker.ThrownException;
812-
methodResult = methodInvoker.MethodResult;
862+
if (closureSafeExceptionThrownOnCmdletThread == null) // stateChangedEventHandler didn't set the results? = ok to clobber results?
863+
{
864+
closureSafeExceptionThrownOnCmdletThread = methodInvoker.ThrownException;
865+
methodResult = methodInvoker.MethodResult;
866+
}
813867
}
814868
}
815869
}

src/Common/Commands.Common/Extensions/CmdletExtensions.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,30 @@ public static void SafeCopyValue<T>(this FieldInfo field, T source, T target)
178178
}
179179
}
180180

181+
/// <summary>
182+
/// Safely copy the selected parameter set from one cmdlet to another
183+
/// </summary>
184+
/// <typeparam name="T">The cmdlet type</typeparam>
185+
/// <param name="source">The cmdlet to copy the parameter set name from</param>
186+
/// <param name="target">The cmdlet to copy to</param>
187+
public static void SafeCopyParameterSet<T>(this T source, T target) where T : AzurePSCmdlet
188+
{
189+
if (source != null && target != null)
190+
{
191+
if (!string.IsNullOrWhiteSpace(source.ParameterSetName))
192+
{
193+
try
194+
{
195+
target.SetParameterSet(source.ParameterSetName);
196+
}
197+
catch
198+
{
199+
200+
}
201+
}
202+
}
203+
}
204+
181205
public static string AsAbsoluteLocation(this string realtivePath)
182206
{
183207
return Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, realtivePath));

0 commit comments

Comments
 (0)