Skip to content

Commit

Permalink
SyncTaskScheduler as a separete class.
Browse files Browse the repository at this point in the history
  • Loading branch information
sergey-shandar committed Nov 30, 2017
1 parent 9176172 commit 526b4b7
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
<Compile Include="StateOperationContext.cs" />
<Compile Include="Compute\ComputeStrategy.cs" />
<Compile Include="Compute\VirtualMachineStrategy.cs" />
<Compile Include="SyncTaskScheduler.cs" />
<Compile Include="UpdateStateExtensions.cs" />
<Compile Include="CreateOrUpdateAsyncParams.cs" />
<Compile Include="EntityConfigExtensions.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,18 @@
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.Azure.Commands.Compute.Strategies
namespace Microsoft.Azure.Commands.Common.Strategies
{
internal sealed class MessageLoop
public sealed class SyncTaskScheduler
{
readonly ConcurrentQueue<Task> _Tasks = new ConcurrentQueue<Task>();

public async Task<T> Invoke<T>(Func<T> func)
{
var task = new Task<T>(func);
_Tasks.Enqueue(task);
// note: don't use 'await' keyword for the 'task' because it may start the task in
// another thread.
while (!task.IsCompleted)
{
await Task.Yield();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,9 @@
<Compile Include="StorageServices\CloudPageBlobObjectFactory.cs" />
<Compile Include="StorageServices\SaveAzureVhdCommand.cs" />
<Compile Include="StorageServices\StorageCredentialsFactory.cs" />
<Compile Include="Strategies\MessageLoop.cs" />
<Compile Include="Strategies\AsyncCmdletExtensions.cs" />
<Compile Include="Strategies\Client.cs" />
<Compile Include="Strategies\IAsyncCmdlet.cs" />
<Compile Include="Strategies\ProgressReport.cs" />
<Compile Include="Strategies\ShouldProcess.cs" />
<Compile Include="Usage\GetAzureVMUsageCommand.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Microsoft.Azure.Commands.Common.Strategies;
using System;
using System.Management.Automation;
using System.Threading.Tasks;

namespace Microsoft.Azure.Commands.Compute.Strategies
{
static class AsyncCmdletExtensions
{
/// <summary>
/// Note: the function must be called in the main PowerShell thread.
/// </summary>
/// <param name="cmdlet"></param>
/// <param name="createAndStartTask"></param>
public static void StartAndWait(this Cmdlet cmdlet, Func<IAsyncCmdlet, Task> createAndStartTask)
{
var asyncCmdlet = new AsyncCmdlet(cmdlet);
asyncCmdlet.Scheduler.Wait(createAndStartTask(asyncCmdlet));
}

sealed class AsyncCmdlet : IAsyncCmdlet
{
public SyncTaskScheduler Scheduler { get; } = new SyncTaskScheduler();

readonly Cmdlet _Cmdlet;

public AsyncCmdlet(Cmdlet cmdlet)
{
_Cmdlet = cmdlet;
}

public void WriteVerbose(string message)
=> Scheduler.BeginInvoke(() => _Cmdlet.WriteVerbose(message));

public Task<bool> ShouldProcessAsync(string target, string action)
=> Scheduler.Invoke(() => _Cmdlet.ShouldProcess(target, action));
}
}
}
25 changes: 25 additions & 0 deletions src/ResourceManager/Compute/Commands.Compute/Strategies/Client.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Microsoft.Azure.Commands.Common.Authentication;
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
using Microsoft.Azure.Commands.Common.Strategies;
using Microsoft.Rest;

namespace Microsoft.Azure.Commands.Compute.Strategies
{
sealed class Client : IClient
{
public string SubscriptionId { get; }

IAzureContext Context { get; }

public Client(IAzureContext context)
{
Context = context;
SubscriptionId = Context.Subscription.Id;
}

public T GetClient<T>()
where T : ServiceClient<T>
=> AzureSession.Instance.ClientFactory.CreateArmClient<T>(
Context, AzureEnvironment.Endpoint.ResourceManager);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Threading.Tasks;

namespace Microsoft.Azure.Commands.Compute.Strategies
{
interface IAsyncCmdlet
{
void WriteVerbose(string message);

Task<bool> ShouldProcessAsync(string target, string action);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,22 @@
// ----------------------------------------------------------------------------------

using Microsoft.Azure.Commands.Common.Strategies;
using System.Management.Automation;

namespace Microsoft.Azure.Commands.Compute.Strategies
{
sealed class ProgressReport : IProgressReport
{
readonly Cmdlet _Cmdlet;
readonly IAsyncCmdlet _Cmdlet;

readonly MessageLoop _MessageLoop;

public ProgressReport(Cmdlet cmdlet, MessageLoop messageLoop)
public ProgressReport(IAsyncCmdlet cmdlet)
{
_Cmdlet = cmdlet;
_MessageLoop = messageLoop;
}

public void Report<TModel>(ResourceConfig<TModel> config, double progress)
where TModel : class
=> _MessageLoop.BeginInvoke(() => _Cmdlet.WriteVerbose(progress == 0
=> _Cmdlet.WriteVerbose(progress == 0
? "Creating " + config.Name + " " + config.Strategy.Type + "..."
: config.Name + " " + config.Strategy.Type + " is created."));
: config.Name + " " + config.Strategy.Type + " is created.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,16 @@ namespace Microsoft.Azure.Commands.Compute.Strategies
{
internal sealed class ShouldProcess : IShouldProcess
{
readonly Cmdlet _Cmdlet;
readonly IAsyncCmdlet _Cmdlet;

readonly MessageLoop _MessageLoop;

public ShouldProcess(Cmdlet cmdlet, MessageLoop messageLoop)
public ShouldProcess(IAsyncCmdlet cmdlet)
{
_Cmdlet = cmdlet;
_MessageLoop = messageLoop;
}

public async Task<bool> ShouldCreate<TModel>(ResourceConfig<TModel> config, TModel model)
public Task<bool> ShouldCreate<TModel>(ResourceConfig<TModel> config, TModel model)
where TModel : class
=> await _MessageLoop.Invoke(
() => _Cmdlet.ShouldProcess(
config.Name, VerbsCommon.New + " " + config.Strategy.Type));
=> _Cmdlet.ShouldProcessAsync(
config.Name, VerbsCommon.New + " " + config.Strategy.Type);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -161,35 +161,15 @@ public override void ExecuteCmdlet()
switch (ParameterSetName)
{
case StrategyParameterSet:
StrategyExecuteCmdlet();
this.StartAndWait(StrategyExecuteCmdletAsync);
break;
default:
DefaultExecuteCmdlet();
break;
}
}

readonly MessageLoop _MessageLoop = new MessageLoop();

private sealed class Client : IClient
{
public string SubscriptionId { get; }

IAzureContext Context { get; }

public Client(IAzureContext context)
{
Context = context;
SubscriptionId = Context.Subscription.Id;
}

public T GetClient<T>()
where T : ServiceClient<T>
=> AzureSession.Instance.ClientFactory.CreateArmClient<T>(
Context, AzureEnvironment.Endpoint.ResourceManager);
}

public async Task StrategyExecuteCmdletAsync()
async Task StrategyExecuteCmdletAsync(IAsyncCmdlet asyncCmdlet)
{
ResourceGroupName = ResourceGroupName ?? Name;
VirtualNetworkName = VirtualNetworkName ?? Name;
Expand Down Expand Up @@ -252,14 +232,11 @@ public async Task StrategyExecuteCmdletAsync()
client,
target,
new CancellationToken(),
new ShouldProcess(this, _MessageLoop),
new ProgressReport(this, _MessageLoop));
new ShouldProcess(asyncCmdlet),
new ProgressReport(asyncCmdlet));
WriteObject(result);
}

public void StrategyExecuteCmdlet()
=> _MessageLoop.Wait(StrategyExecuteCmdletAsync());

public void DefaultExecuteCmdlet()
{
base.ExecuteCmdlet();
Expand Down

0 comments on commit 526b4b7

Please sign in to comment.