Introduce ScenarioExecutionContext.

pull/975/head
Halil ibrahim Kalkan 7 years ago
parent 69104bc79a
commit d9e4ac32a9

@ -1,11 +1,13 @@
using Volo.Abp;
using System;
using Volo.Abp;
using Volo.ClientSimulation.Scenarios;
namespace Volo.ClientSimulation.Demo.Scenarios
{
public class DemoScenario : Scenario
{
public DemoScenario()
public DemoScenario(IServiceProvider serviceProvider) :
base(serviceProvider)
{
AddStep(new SleepScenarioStep("Wait1", RandomHelper.GetRandom(1000, 5000)));
AddStep(new SleepScenarioStep("Wait2", RandomHelper.GetRandom(2000, 6000)));

@ -24,12 +24,4 @@
<None Remove="Logs\**" />
</ItemGroup>
<ItemGroup>
<Content Remove="compilerconfig.json" />
</ItemGroup>
<ItemGroup>
<None Include="compilerconfig.json" />
</ItemGroup>
</Project>

@ -57,25 +57,52 @@
Scenarios
</abp-card-header>
<abp-card-body>
<abp-row>
@foreach (var scenario in Model.Snapshot.Scenarios)
{
<abp-column size-md="_6">
<abp-card>
<abp-card class="simulation-scenario">
<abp-card-header>
@scenario.DisplayText
</abp-card-header>
<abp-card-body>
<pre>
@foreach (var step in scenario.Steps)
{
<text>@step.DisplayText: E: @step.ExecutionCount | S: @step.SuccessCount | A: @step.AvgExecutionDuration.ToString("0.00") ms. </text>@Environment.NewLine
}
</pre>
<abp-table>
<thead>
<tr>
<th>Step</th>
<th>Execution</th>
<th>Success</th>
<th>Fail</th>
<th>Min</th>
<th>Max</th>
<th>Avg</th>
</tr>
</thead>
<tbody>
@foreach (var step in scenario.Steps)
{
<tr>
<th>@step.DisplayText</th>
<th>@step.ExecutionCount</th>
<th>@step.SuccessCount</th>
<th>
@if (step.FailCount > 0)
{
<span class="step-positive-fail-count">@step.FailCount</span>
}
else
{
<text>@step.FailCount</text>
}
</th>
<th>@step.MinExecutionDuration.ToString("0.0") ms</th>
<th>@step.MaxExecutionDuration.ToString("0.0") ms</th>
<th>@step.AvgExecutionDuration.ToString("0.0") ms</th>
</tr>
}
</tbody>
</abp-table>
</abp-card-body>
</abp-card>
</abp-column>
}
</abp-row>
</abp-card-body>
</abp-card>

@ -21,3 +21,6 @@
background-color: #fde0d7; }
.simulation-client.simulation-client-stopping .simulation-client-icon {
color: #f88562; }
.simulation-scenario .step-positive-fail-count {
color: red; }

@ -1 +1 @@
.simulation-client{border:1px solid #008000;background-color:#f5f5f5;margin:3px;padding:5px;min-width:250px;overflow:hidden;display:inline-block;}.simulation-client .simulation-client-icon{color:#999;}.simulation-client .simulation-client-scenario{font-weight:bold;}.simulation-client .simulation-client-scenario-current-step{color:#666;font-size:.8em;}.simulation-client.simulation-client-running{background-color:#d6ffce;}.simulation-client.simulation-client-running .simulation-client-icon{color:#008000;}.simulation-client.simulation-client-stopping{background-color:#fde0d7;}.simulation-client.simulation-client-stopping .simulation-client-icon{color:#f88562;}
.simulation-client{border:1px solid #008000;background-color:#f5f5f5;margin:3px;padding:5px;min-width:250px;overflow:hidden;display:inline-block;}.simulation-client .simulation-client-icon{color:#999;}.simulation-client .simulation-client-scenario{font-weight:bold;}.simulation-client .simulation-client-scenario-current-step{color:#666;font-size:.8em;}.simulation-client.simulation-client-running{background-color:#d6ffce;}.simulation-client.simulation-client-running .simulation-client-icon{color:#008000;}.simulation-client.simulation-client-stopping{background-color:#fde0d7;}.simulation-client.simulation-client-stopping .simulation-client-icon{color:#f88562;}.simulation-scenario .step-positive-fail-count{color:#f00;}

@ -36,3 +36,9 @@
}
}
}
.simulation-scenario {
.step-positive-fail-count {
color: red;
}
}

@ -25,7 +25,9 @@
<Content Remove="Pages\**\*.js" />
<Content Remove="Pages\**\*.css" />
<Content Remove="Pages\**\*.scss" />
<Content Remove="compilerconfig.json" />
<Content Remove="Properties\launchSettings.json" />
<None Include="compilerconfig.json" />
<None Include="Properties\launchSettings.json" />
</ItemGroup>

@ -12,8 +12,6 @@ namespace Volo.ClientSimulation.Clients
{
public event EventHandler Stopped;
public Scenario Scenario { get; private set; }
public ClientState State
{
get => _state;
@ -21,9 +19,10 @@ namespace Volo.ClientSimulation.Clients
}
private volatile ClientState _state;
private Thread _thread;
protected Scenario Scenario { get; private set; }
protected object SyncLock { get; } = new object();
protected readonly object SyncLock = new object();
protected Thread ClientThread;
public void Initialize(Scenario scenario)
{
@ -50,8 +49,8 @@ namespace Volo.ClientSimulation.Clients
State = ClientState.Running;
Scenario.Reset();
_thread = new Thread(Run);
_thread.Start();
ClientThread = new Thread(Run);
ClientThread.Start();
}
}
@ -89,7 +88,7 @@ namespace Volo.ClientSimulation.Clients
if (State != ClientState.Running)
{
State = ClientState.Stopped;
_thread = null;
ClientThread = null;
Stopped.InvokeSafely(this);
break;
}

@ -8,8 +8,6 @@ namespace Volo.ClientSimulation.Clients
{
event EventHandler Stopped;
Scenario Scenario { get; }
ClientState State { get; }
void Initialize(Scenario scenario);

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
@ -22,13 +23,26 @@ namespace Volo.ClientSimulation.Scenarios
protected int CurrentStepIndex { get; set; }
protected Scenario()
protected ScenarioExecutionContext ExecutionContext { get; }
protected Scenario(IServiceProvider serviceProvider)
{
ExecutionContext = new ScenarioExecutionContext(serviceProvider);
Steps = new List<ScenarioStep>();
}
public virtual string GetDisplayText()
{
var displayNameAttr = GetType()
.GetCustomAttributes(true)
.OfType<DisplayNameAttribute>()
.FirstOrDefault();
if (displayNameAttr != null)
{
return displayNameAttr.DisplayName;
}
return GetType()
.Name
.RemovePostFix(nameof(Scenario));
@ -38,7 +52,7 @@ namespace Volo.ClientSimulation.Scenarios
{
CheckStepCount();
await Steps[CurrentStepIndex].RunAsync();
await Steps[CurrentStepIndex].RunAsync(ExecutionContext);
CurrentStepIndex++;
@ -51,10 +65,13 @@ namespace Volo.ClientSimulation.Scenarios
public void Reset()
{
CurrentStepIndex = 0;
foreach (var step in Steps)
{
step.Reset();
}
ExecutionContext.Reset();
}
public ScenarioSnapshot CreateSnapshot()

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
namespace Volo.ClientSimulation.Scenarios
{
public class ScenarioExecutionContext
{
public IServiceProvider ServiceProvider { get; }
public Dictionary<string, object> Properties { get; }
public ScenarioExecutionContext(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
Properties = new Dictionary<string, object>();
}
public virtual void Reset()
{
Properties.Clear();
}
}
}

@ -1,6 +1,11 @@
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Resources;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using Volo.ClientSimulation.Snapshot;
namespace Volo.ClientSimulation.Scenarios
@ -15,27 +20,17 @@ namespace Volo.ClientSimulation.Scenarios
protected double MaxExecutionDuration;
protected double LastExecutionDuration;
public async Task RunAsync()
public async Task RunAsync(ScenarioExecutionContext context)
{
await BeforeExecuteAsync();
await BeforeExecuteAsync(context);
var stopwatch = Stopwatch.StartNew();
try
{
await ExecuteAsync();
SuccessCount++;
}
catch
{
//TODO: Log!
FailCount++;
}
finally
{
stopwatch.Stop();
await ExecuteAsync(context);
ExecutionCount++;
SuccessCount++;
LastExecutionDuration = stopwatch.Elapsed.TotalMilliseconds;
@ -51,24 +46,49 @@ namespace Volo.ClientSimulation.Scenarios
MaxExecutionDuration = LastExecutionDuration;
}
}
catch(Exception ex)
{
FailCount++;
context
.ServiceProvider
.GetService<ILogger<ScenarioStep>>()
.LogException(ex);
}
finally
{
stopwatch.Stop();
ExecutionCount++;
}
await AfterExecuteAsync();
await AfterExecuteAsync(context);
}
protected virtual Task BeforeExecuteAsync()
protected virtual Task BeforeExecuteAsync(ScenarioExecutionContext context)
{
return Task.CompletedTask;
}
protected abstract Task ExecuteAsync();
protected abstract Task ExecuteAsync(ScenarioExecutionContext context);
protected virtual Task AfterExecuteAsync()
protected virtual Task AfterExecuteAsync(ScenarioExecutionContext context)
{
return Task.CompletedTask;
}
public virtual string GetDisplayText()
{
var displayNameAttr = GetType()
.GetCustomAttributes(true)
.OfType<DisplayNameAttribute>()
.FirstOrDefault();
if (displayNameAttr != null)
{
return displayNameAttr.DisplayName;
}
return GetType()
.Name
.RemovePostFix(nameof(ScenarioStep));
@ -84,9 +104,9 @@ namespace Volo.ClientSimulation.Scenarios
MaxExecutionDuration = MaxExecutionDuration,
MinExecutionDuration = MinExecutionDuration,
TotalExecutionDuration = TotalExecutionDuration,
AvgExecutionDuration = ExecutionCount == 0
AvgExecutionDuration = SuccessCount == 0
? 0.0
: TotalExecutionDuration / ExecutionCount,
: TotalExecutionDuration / SuccessCount,
FailCount = FailCount,
SuccessCount = SuccessCount
};

@ -8,13 +8,15 @@ namespace Volo.ClientSimulation.Scenarios
public int Duration { get; }
public SleepScenarioStep(string name, int duration = 1000)
public SleepScenarioStep(
string name,
int duration = 1000)
{
Name = name;
Duration = duration;
}
protected override Task ExecuteAsync()
protected override Task ExecuteAsync(ScenarioExecutionContext context)
{
return Task.Delay(Duration);
}

@ -17,15 +17,19 @@ namespace Volo.ClientSimulation
{
public ILogger<Simulation> Logger { get; set; }
public SimulationState State { get; private set; }
public SimulationState State
{
get => _state;
private set => _state = value;
}
private volatile SimulationState _state;
public List<IClient> Clients { get; }
protected ClientSimulationOptions Options { get; }
protected IServiceScopeFactory ServiceScopeFactory { get; }
protected IServiceScope ServiceScope { get; private set; }
protected readonly object SyncObj = new object();
protected object SyncObj { get; } = new object();
public Simulation(
IServiceScopeFactory serviceScopeFactory,

@ -56,9 +56,9 @@ namespace Volo.ClientSimulation.Snapshot
scenarioStepSummary.MaxExecutionDuration = scenarioStep.MaxExecutionDuration;
}
scenarioStepSummary.AvgExecutionDuration = scenarioStepSummary.ExecutionCount == 0
scenarioStepSummary.AvgExecutionDuration = scenarioStepSummary.SuccessCount == 0
? 0.0
: scenarioStepSummary.TotalExecutionDuration / scenarioStepSummary.ExecutionCount;
: scenarioStepSummary.TotalExecutionDuration / scenarioStepSummary.SuccessCount;
}
}

Loading…
Cancel
Save