From d9e4ac32a91731d1c1e40d1c74a050b7d76b7053 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Sun, 7 Apr 2019 19:28:32 +0300 Subject: [PATCH] Introduce ScenarioExecutionContext. --- .../Scenarios/DemoScenario.cs | 6 +- .../Volo.ClientSimulation.Demo.csproj | 8 --- .../ClientSimulation/SimulationArea.cshtml | 49 +++++++++++---- .../Pages/ClientSimulation/SimulationArea.css | 3 + .../ClientSimulation/SimulationArea.min.css | 2 +- .../ClientSimulation/SimulationArea.scss | 6 ++ .../Volo.ClientSimulation.Web.csproj | 2 + .../compilerconfig.json | 0 .../compilerconfig.json.defaults | 0 .../Volo/ClientSimulation/Clients/Client.cs | 13 ++-- .../Volo/ClientSimulation/Clients/IClient.cs | 2 - .../ClientSimulation/Scenarios/Scenario.cs | 21 ++++++- .../Scenarios/ScenarioExecutionContext.cs | 23 +++++++ .../Scenarios/ScenarioStep.cs | 60 ++++++++++++------- .../Scenarios/SleepScenarioStep.cs | 6 +- .../Volo/ClientSimulation/Simulation.cs | 10 +++- .../Snapshot/SimulationSnapshot.cs | 4 +- 17 files changed, 155 insertions(+), 60 deletions(-) rename modules/client-simulation/{demo/Volo.ClientSimulation.Demo => src/Volo.ClientSimulation.Web}/compilerconfig.json (100%) rename modules/client-simulation/{demo/Volo.ClientSimulation.Demo => src/Volo.ClientSimulation.Web}/compilerconfig.json.defaults (100%) create mode 100644 modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/ScenarioExecutionContext.cs diff --git a/modules/client-simulation/demo/Volo.ClientSimulation.Demo/Scenarios/DemoScenario.cs b/modules/client-simulation/demo/Volo.ClientSimulation.Demo/Scenarios/DemoScenario.cs index 55a3de0a9a..0116f11183 100644 --- a/modules/client-simulation/demo/Volo.ClientSimulation.Demo/Scenarios/DemoScenario.cs +++ b/modules/client-simulation/demo/Volo.ClientSimulation.Demo/Scenarios/DemoScenario.cs @@ -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))); diff --git a/modules/client-simulation/demo/Volo.ClientSimulation.Demo/Volo.ClientSimulation.Demo.csproj b/modules/client-simulation/demo/Volo.ClientSimulation.Demo/Volo.ClientSimulation.Demo.csproj index 98aeb84b25..089a2ca3ab 100644 --- a/modules/client-simulation/demo/Volo.ClientSimulation.Demo/Volo.ClientSimulation.Demo.csproj +++ b/modules/client-simulation/demo/Volo.ClientSimulation.Demo/Volo.ClientSimulation.Demo.csproj @@ -24,12 +24,4 @@ - - - - - - - - diff --git a/modules/client-simulation/src/Volo.ClientSimulation.Web/Pages/ClientSimulation/SimulationArea.cshtml b/modules/client-simulation/src/Volo.ClientSimulation.Web/Pages/ClientSimulation/SimulationArea.cshtml index 46e27b6eb3..77aa653efe 100644 --- a/modules/client-simulation/src/Volo.ClientSimulation.Web/Pages/ClientSimulation/SimulationArea.cshtml +++ b/modules/client-simulation/src/Volo.ClientSimulation.Web/Pages/ClientSimulation/SimulationArea.cshtml @@ -57,25 +57,52 @@ Scenarios - @foreach (var scenario in Model.Snapshot.Scenarios) { - - + @scenario.DisplayText -
-@foreach (var step in scenario.Steps)
-{
-    @step.DisplayText: E: @step.ExecutionCount | S: @step.SuccessCount | A: @step.AvgExecutionDuration.ToString("0.00") ms. @Environment.NewLine
-}
-
+ + + + Step + Execution + Success + Fail + Min + Max + Avg + + + + @foreach (var step in scenario.Steps) + { + + @step.DisplayText + @step.ExecutionCount + @step.SuccessCount + + @if (step.FailCount > 0) + { + @step.FailCount + } + else + { + @step.FailCount + } + + @step.MinExecutionDuration.ToString("0.0") ms + @step.MaxExecutionDuration.ToString("0.0") ms + @step.AvgExecutionDuration.ToString("0.0") ms + + } + + +
-
} -
\ No newline at end of file diff --git a/modules/client-simulation/src/Volo.ClientSimulation.Web/Pages/ClientSimulation/SimulationArea.css b/modules/client-simulation/src/Volo.ClientSimulation.Web/Pages/ClientSimulation/SimulationArea.css index 1df331259f..8a4e304726 100644 --- a/modules/client-simulation/src/Volo.ClientSimulation.Web/Pages/ClientSimulation/SimulationArea.css +++ b/modules/client-simulation/src/Volo.ClientSimulation.Web/Pages/ClientSimulation/SimulationArea.css @@ -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; } diff --git a/modules/client-simulation/src/Volo.ClientSimulation.Web/Pages/ClientSimulation/SimulationArea.min.css b/modules/client-simulation/src/Volo.ClientSimulation.Web/Pages/ClientSimulation/SimulationArea.min.css index dc51bea15a..551f57f349 100644 --- a/modules/client-simulation/src/Volo.ClientSimulation.Web/Pages/ClientSimulation/SimulationArea.min.css +++ b/modules/client-simulation/src/Volo.ClientSimulation.Web/Pages/ClientSimulation/SimulationArea.min.css @@ -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;} \ No newline at end of file +.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;} \ No newline at end of file diff --git a/modules/client-simulation/src/Volo.ClientSimulation.Web/Pages/ClientSimulation/SimulationArea.scss b/modules/client-simulation/src/Volo.ClientSimulation.Web/Pages/ClientSimulation/SimulationArea.scss index 9f1abbc765..6328397010 100644 --- a/modules/client-simulation/src/Volo.ClientSimulation.Web/Pages/ClientSimulation/SimulationArea.scss +++ b/modules/client-simulation/src/Volo.ClientSimulation.Web/Pages/ClientSimulation/SimulationArea.scss @@ -36,3 +36,9 @@ } } } + +.simulation-scenario { + .step-positive-fail-count { + color: red; + } +} diff --git a/modules/client-simulation/src/Volo.ClientSimulation.Web/Volo.ClientSimulation.Web.csproj b/modules/client-simulation/src/Volo.ClientSimulation.Web/Volo.ClientSimulation.Web.csproj index 753de2f80b..92fdeb6d4c 100644 --- a/modules/client-simulation/src/Volo.ClientSimulation.Web/Volo.ClientSimulation.Web.csproj +++ b/modules/client-simulation/src/Volo.ClientSimulation.Web/Volo.ClientSimulation.Web.csproj @@ -25,7 +25,9 @@ + + diff --git a/modules/client-simulation/demo/Volo.ClientSimulation.Demo/compilerconfig.json b/modules/client-simulation/src/Volo.ClientSimulation.Web/compilerconfig.json similarity index 100% rename from modules/client-simulation/demo/Volo.ClientSimulation.Demo/compilerconfig.json rename to modules/client-simulation/src/Volo.ClientSimulation.Web/compilerconfig.json diff --git a/modules/client-simulation/demo/Volo.ClientSimulation.Demo/compilerconfig.json.defaults b/modules/client-simulation/src/Volo.ClientSimulation.Web/compilerconfig.json.defaults similarity index 100% rename from modules/client-simulation/demo/Volo.ClientSimulation.Demo/compilerconfig.json.defaults rename to modules/client-simulation/src/Volo.ClientSimulation.Web/compilerconfig.json.defaults diff --git a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/Client.cs b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/Client.cs index b56f733f6f..0d74b18077 100644 --- a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/Client.cs +++ b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/Client.cs @@ -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; } diff --git a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IClient.cs b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IClient.cs index 918dcc5d34..597e14c9e0 100644 --- a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IClient.cs +++ b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IClient.cs @@ -8,8 +8,6 @@ namespace Volo.ClientSimulation.Clients { event EventHandler Stopped; - Scenario Scenario { get; } - ClientState State { get; } void Initialize(Scenario scenario); diff --git a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/Scenario.cs b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/Scenario.cs index 752cafbe26..02b30f5f20 100644 --- a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/Scenario.cs +++ b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/Scenario.cs @@ -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(); } public virtual string GetDisplayText() { + var displayNameAttr = GetType() + .GetCustomAttributes(true) + .OfType() + .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() diff --git a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/ScenarioExecutionContext.cs b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/ScenarioExecutionContext.cs new file mode 100644 index 0000000000..a88a580670 --- /dev/null +++ b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/ScenarioExecutionContext.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; + +namespace Volo.ClientSimulation.Scenarios +{ + public class ScenarioExecutionContext + { + public IServiceProvider ServiceProvider { get; } + + public Dictionary Properties { get; } + + public ScenarioExecutionContext(IServiceProvider serviceProvider) + { + ServiceProvider = serviceProvider; + Properties = new Dictionary(); + } + + public virtual void Reset() + { + Properties.Clear(); + } + } +} \ No newline at end of file diff --git a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/ScenarioStep.cs b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/ScenarioStep.cs index 8e150895f1..fe9255fcb3 100644 --- a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/ScenarioStep.cs +++ b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/ScenarioStep.cs @@ -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>() + .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() + .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 }; diff --git a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/SleepScenarioStep.cs b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/SleepScenarioStep.cs index 42c350b26b..d2e462cf9f 100644 --- a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/SleepScenarioStep.cs +++ b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/SleepScenarioStep.cs @@ -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); } diff --git a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Simulation.cs b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Simulation.cs index bfa464d8d1..4f0d7240dc 100644 --- a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Simulation.cs +++ b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Simulation.cs @@ -17,15 +17,19 @@ namespace Volo.ClientSimulation { public ILogger Logger { get; set; } - public SimulationState State { get; private set; } + public SimulationState State + { + get => _state; + private set => _state = value; + } + private volatile SimulationState _state; public List 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, diff --git a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Snapshot/SimulationSnapshot.cs b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Snapshot/SimulationSnapshot.cs index 6e03ae231e..c981f55a12 100644 --- a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Snapshot/SimulationSnapshot.cs +++ b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Snapshot/SimulationSnapshot.cs @@ -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; } }