Skip to content

Commit bcb9a26

Browse files
MessageLoop, kind of.
1 parent dba029c commit bcb9a26

File tree

7 files changed

+114
-46
lines changed

7 files changed

+114
-46
lines changed

src/ResourceManager/Common/Commands.Common.Strategies/IShouldProcess.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
// limitations under the License.
1313
// ----------------------------------------------------------------------------------
1414

15+
using System.Threading.Tasks;
16+
1517
namespace Microsoft.Azure.Commands.Common.Strategies
1618
{
1719
public interface IShouldProcess
1820
{
19-
bool ShouldCreate<TModel>(ResourceConfig<TModel> config, TModel model)
21+
Task<bool> ShouldCreate<TModel>(ResourceConfig<TModel> config, TModel model)
2022
where TModel : class;
2123
}
2224
}

src/ResourceManager/Common/Commands.Common.Strategies/UpdateStateExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ await _OperationContext.GetOrAdd(
7878
.Select(UpdateStateAsyncDispatch);
7979
await Task.WhenAll(tasks);
8080
// call the CreateOrUpdateAsync function for the resource.
81-
if (_ShouldProcess.ShouldCreate(config, model))
81+
if (await _ShouldProcess.ShouldCreate(config, model))
8282
{
8383
_ProgressReport.Report(config, 0.0);
8484
var result = await config.CreateOrUpdateAsync(

src/ResourceManager/Compute/Commands.Compute/Commands.Compute.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,9 @@
290290
<Compile Include="StorageServices\CloudPageBlobObjectFactory.cs" />
291291
<Compile Include="StorageServices\SaveAzureVhdCommand.cs" />
292292
<Compile Include="StorageServices\StorageCredentialsFactory.cs" />
293+
<Compile Include="Strategies\MessageLoop.cs" />
294+
<Compile Include="Strategies\ProgressReport.cs" />
295+
<Compile Include="Strategies\ShouldProcess.cs" />
293296
<Compile Include="Usage\GetAzureVMUsageCommand.cs" />
294297
<Compile Include="Usage\VirtualMachineUsageBaseCmdlet.cs" />
295298
<Compile Include="VirtualMachineSizes\GetAzureVMSizeCommand.cs" />
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
using System.Collections.Concurrent;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
6+
namespace Microsoft.Azure.Commands.Compute.Strategies
7+
{
8+
internal sealed class MessageLoop
9+
{
10+
readonly ConcurrentQueue<Task> _Tasks = new ConcurrentQueue<Task>();
11+
12+
public async Task<T> Invoke<T>(Func<T> func)
13+
{
14+
var task = new Task<T>(func);
15+
_Tasks.Enqueue(task);
16+
while (!task.IsCompleted)
17+
{
18+
await Task.Yield();
19+
}
20+
return task.Result;
21+
}
22+
23+
public void BeginInvoke(Action action)
24+
=> _Tasks.Enqueue(new Task(action));
25+
26+
public void Wait(Task task)
27+
{
28+
while (!task.IsCompleted)
29+
{
30+
HandleActions();
31+
Thread.Yield();
32+
}
33+
HandleActions();
34+
}
35+
36+
void HandleActions()
37+
{
38+
Task task;
39+
while (_Tasks.TryDequeue(out task))
40+
{
41+
task.RunSynchronously();
42+
}
43+
}
44+
}
45+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using Microsoft.Azure.Commands.Common.Strategies;
2+
using System.Management.Automation;
3+
4+
namespace Microsoft.Azure.Commands.Compute.Strategies
5+
{
6+
sealed class ProgressReport : IProgressReport
7+
{
8+
readonly Cmdlet _Cmdlet;
9+
10+
readonly MessageLoop _MessageLoop;
11+
12+
public ProgressReport(Cmdlet cmdlet, MessageLoop messageLoop)
13+
{
14+
_Cmdlet = cmdlet;
15+
_MessageLoop = messageLoop;
16+
}
17+
18+
public void Report<TModel>(ResourceConfig<TModel> config, double progress)
19+
where TModel : class
20+
=> _MessageLoop.BeginInvoke(() => _Cmdlet.WriteVerbose(progress == 0
21+
? "Creating " + config.Name + " " + config.Strategy.Type + "..."
22+
: config.Name + " " + config.Strategy.Type + " is created."));
23+
}
24+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using Microsoft.Azure.Commands.Common.Strategies;
2+
using System.Management.Automation;
3+
using System.Threading.Tasks;
4+
5+
namespace Microsoft.Azure.Commands.Compute.Strategies
6+
{
7+
internal sealed class ShouldProcess : IShouldProcess
8+
{
9+
readonly Cmdlet _Cmdlet;
10+
11+
readonly MessageLoop _MessageLoop;
12+
13+
public ShouldProcess(Cmdlet cmdlet, MessageLoop messageLoop)
14+
{
15+
_Cmdlet = cmdlet;
16+
_MessageLoop = messageLoop;
17+
}
18+
19+
public async Task<bool> ShouldCreate<TModel>(ResourceConfig<TModel> config, TModel model)
20+
where TModel : class
21+
=> await _MessageLoop.Invoke(
22+
() => _Cmdlet.ShouldProcess(
23+
config.Name, VerbsCommon.New + " " + config.Strategy.Type));
24+
}
25+
}

src/ResourceManager/Compute/Commands.Compute/VirtualMachine/Operation/NewAzureVMCommand.cs

Lines changed: 13 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
using Microsoft.Azure.Commands.Common.Strategies.ResourceManager;
2323
using Microsoft.Azure.Commands.Compute.Common;
2424
using Microsoft.Azure.Commands.Compute.Models;
25+
using Microsoft.Azure.Commands.Compute.Strategies;
2526
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
2627
using Microsoft.Azure.Management.Compute;
2728
using Microsoft.Azure.Management.Compute.Models;
@@ -32,11 +33,13 @@
3233
using Microsoft.Rest;
3334
using System;
3435
using System.Collections;
36+
using System.Collections.Concurrent;
3537
using System.Linq;
3638
using System.Management.Automation;
3739
using System.Net;
3840
using System.Reflection;
3941
using System.Threading;
42+
using System.Threading.Tasks;
4043
using CM = Microsoft.Azure.Management.Compute.Models;
4144

4245
namespace Microsoft.Azure.Commands.Compute
@@ -166,6 +169,8 @@ public override void ExecuteCmdlet()
166169
}
167170
}
168171

172+
readonly MessageLoop _MessageLoop = new MessageLoop();
173+
169174
private sealed class Client : IClient
170175
{
171176
public string SubscriptionId { get; }
@@ -184,41 +189,7 @@ public T GetClient<T>()
184189
Context, AzureEnvironment.Endpoint.ResourceManager);
185190
}
186191

187-
private sealed class ShouldProcessType : IShouldProcess
188-
{
189-
readonly Cmdlet _Cmdlet;
190-
191-
public ShouldProcessType(Cmdlet cmdlet)
192-
{
193-
_Cmdlet = cmdlet;
194-
}
195-
196-
public bool ShouldCreate<TModel>(ResourceConfig<TModel> config, TModel model)
197-
where TModel : class
198-
=> _Cmdlet.ShouldProcess(config.Name, VerbsCommon.New + " " + config.Strategy.Type);
199-
}
200-
201-
private sealed class ProgressReportType : IProgressReport
202-
{
203-
readonly Cmdlet _Cmdlet;
204-
205-
public ProgressReportType(Cmdlet cmdlet)
206-
{
207-
_Cmdlet = cmdlet;
208-
}
209-
210-
public void Report<TModel>(ResourceConfig<TModel> config, double progress)
211-
where TModel : class
212-
{
213-
}
214-
/*
215-
=> _Cmdlet.WriteVerbose(
216-
progress == 0 ? "Creating " + config.Name + " " + config.Strategy.Type + "..."
217-
: config.Name + " " + config.Strategy.Type + " is created.");
218-
*/
219-
}
220-
221-
public void StrategyExecuteCmdlet()
192+
public async Task StrategyExecuteCmdletAsync()
222193
{
223194
ResourceGroupName = ResourceGroupName ?? Name;
224195
VirtualNetworkName = VirtualNetworkName ?? Name;
@@ -261,10 +232,7 @@ public void StrategyExecuteCmdlet()
261232

262233
// get state
263234
var client = new Client(DefaultProfile.DefaultContext);
264-
var current = virtualMachine
265-
.GetStateAsync(client, new CancellationToken())
266-
.GetAwaiter()
267-
.GetResult();
235+
var current = await virtualMachine.GetStateAsync(client, new CancellationToken());
268236

269237
if (Location == null)
270238
{
@@ -279,18 +247,19 @@ public void StrategyExecuteCmdlet()
279247
var target = virtualMachine.GetTargetState(current, client.SubscriptionId, Location);
280248

281249
// apply target state
282-
var result = virtualMachine
250+
var result = await virtualMachine
283251
.UpdateStateAsync(
284252
client,
285253
target,
286254
new CancellationToken(),
287-
new ShouldProcessType(this),
288-
new ProgressReportType(this))
289-
.GetAwaiter()
290-
.GetResult();
255+
new ShouldProcess(this, _MessageLoop),
256+
new ProgressReport(this, _MessageLoop));
291257
WriteObject(result);
292258
}
293259

260+
public void StrategyExecuteCmdlet()
261+
=> _MessageLoop.Wait(StrategyExecuteCmdletAsync());
262+
294263
public void DefaultExecuteCmdlet()
295264
{
296265
base.ExecuteCmdlet();

0 commit comments

Comments
 (0)