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 73ffe8aa17..aa8de38b3f 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 @@ -19,30 +19,30 @@ - @foreach (var clientHandler in Model.Simulation.ActiveClients) + @foreach (var client in Model.Simulation.Clients) { - + - @if (clientHandler.Client.State == ClientState.Running) + @if (client.State == ClientState.Running) { } - else if (clientHandler.Client.State == ClientState.Stopping) + else if (client.State == ClientState.Stopping) { } - else if (clientHandler.Client.State == ClientState.Stopped) + else if (client.State == ClientState.Stopped) { } - @clientHandler.Client.Scenario.GetDisplayText() + @client.Scenario.GetDisplayText() - @if (clientHandler.Client.State != ClientState.Stopped) + @if (client.State != ClientState.Stopped) { - | @clientHandler.Client.Scenario.CurrentStep.GetDisplayText() + | @client.Scenario.CurrentStep.GetDisplayText() } 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 6ec7d9b9c5..3d4f303799 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 @@ -1,12 +1,14 @@ -using System; -using System.Threading; +using System.Threading; +using Volo.Abp; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Threading; using Volo.ClientSimulation.Scenarios; namespace Volo.ClientSimulation.Clients { - public class Client : IClient + public class Client : IClient, ITransientDependency { - public IScenario Scenario { get; } + public Scenario Scenario { get; private set; } public ClientState State { @@ -19,7 +21,7 @@ namespace Volo.ClientSimulation.Clients protected readonly object SyncLock = new object(); - public Client(IScenario scenario) + public void Initialize(Scenario scenario) { Scenario = scenario; } @@ -30,7 +32,7 @@ namespace Volo.ClientSimulation.Clients { if (State != ClientState.Stopped) { - throw new ApplicationException("State is not stopped. It is " + State); + throw new UserFriendlyException($"Client should be stopped to be able to start it. Current state is '{State}'."); } State = ClientState.Running; @@ -55,12 +57,21 @@ namespace Volo.ClientSimulation.Clients private void Run() { - while (State == ClientState.Running) + Scenario.Reset(); + + while (true) { - Scenario.Proceed(); - } + lock (SyncLock) + { + if (State != ClientState.Running) + { + State = ClientState.Stopped; + break; + } + } - State = ClientState.Stopped; + AsyncHelper.RunSync(() => Scenario.ProceedAsync()); + } } } } \ No newline at end of file diff --git a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/DefaultClientFactory.cs b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/DefaultClientFactory.cs deleted file mode 100644 index 8015f58b86..0000000000 --- a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/DefaultClientFactory.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Volo.Abp.DependencyInjection; -using Volo.ClientSimulation.Scenarios; - -namespace Volo.ClientSimulation.Clients -{ - public class DefaultClientFactory : IClientFactory, ISingletonDependency - { - public IDisposableClientHandler Create(IScenario scenario) - { - return new DisposableClientHandler(new Client(scenario)); - } - } -} \ No newline at end of file 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 a882259a18..790c1df553 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 @@ -4,10 +4,12 @@ namespace Volo.ClientSimulation.Clients { public interface IClient { - IScenario Scenario { get; } + Scenario Scenario { get; } ClientState State { get; } + void Initialize(Scenario scenario); + void Start(); void Stop(); diff --git a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IClientFactory.cs b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IClientFactory.cs deleted file mode 100644 index b519cb086f..0000000000 --- a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IClientFactory.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Volo.ClientSimulation.Scenarios; - -namespace Volo.ClientSimulation.Clients -{ - public interface IClientFactory - { - IDisposableClientHandler Create(IScenario scenario); - } -} diff --git a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IDisposableClientHandler.cs b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IDisposableClientHandler.cs deleted file mode 100644 index 7d9799823e..0000000000 --- a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IDisposableClientHandler.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; - -namespace Volo.ClientSimulation.Clients -{ - public interface IDisposableClientHandler : IDisposable - { - IClient Client { get; } - } - - public class DisposableClientHandler : IDisposableClientHandler - { - public IClient Client { get; } - - public DisposableClientHandler(IClient client) - { - Client = client; - } - - public virtual void Dispose() - { - - } - } -} \ No newline at end of file diff --git a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/IScenario.cs b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/IScenario.cs deleted file mode 100644 index 951315dc5c..0000000000 --- a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/IScenario.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Collections.Generic; - -namespace Volo.ClientSimulation.Scenarios -{ - public interface IScenario - { - IReadOnlyList Steps { get; } - - IScenarioStep CurrentStep { get; } - - int CurrentStepIndex { get; } - - string GetDisplayText(); - - void Proceed(); - } -} \ No newline at end of file diff --git a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/IScenarioStep.cs b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/IScenarioStep.cs deleted file mode 100644 index 0ec37ebaf4..0000000000 --- a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/IScenarioStep.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Volo.ClientSimulation.Scenarios -{ - public interface IScenarioStep - { - void Run(); - - string GetDisplayText(); - } -} \ No newline at end of file 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 51fb952d35..ec35580a43 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,16 +1,17 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Threading.Tasks; using Volo.Abp.DependencyInjection; namespace Volo.ClientSimulation.Scenarios { - public abstract class Scenario : IScenario, ITransientDependency + public abstract class Scenario : ITransientDependency { - public IReadOnlyList Steps => StepList.ToImmutableList(); - protected List StepList { get; } + public IReadOnlyList Steps => StepList.ToImmutableList(); + protected List StepList { get; } - public IScenarioStep CurrentStep + public ScenarioStep CurrentStep { get { @@ -22,7 +23,7 @@ namespace Volo.ClientSimulation.Scenarios protected Scenario() { - StepList = new List(); + StepList = new List(); } public virtual string GetDisplayText() @@ -32,11 +33,11 @@ namespace Volo.ClientSimulation.Scenarios .RemovePostFix(nameof(Scenario)); } - public virtual void Proceed() + public virtual async Task ProceedAsync() { CheckStepCount(); - StepList[CurrentStepIndex].Run(); + await StepList[CurrentStepIndex].RunAsync(); CurrentStepIndex++; @@ -46,6 +47,11 @@ namespace Volo.ClientSimulation.Scenarios } } + public void Reset() + { + CurrentStepIndex = 0; + } + private void CheckStepCount() { if (StepList.Count <= 0) @@ -56,7 +62,7 @@ namespace Volo.ClientSimulation.Scenarios } } - protected void AddStep(IScenarioStep step) + protected void AddStep(ScenarioStep step) { StepList.Add(step); } 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 2751b5d35e..e21c6d4cd1 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,10 +1,44 @@ using System; +using System.Diagnostics; +using System.Threading.Tasks; namespace Volo.ClientSimulation.Scenarios { - public abstract class ScenarioStep : IScenarioStep + public abstract class ScenarioStep { - public abstract void Run(); + public async Task RunAsync() + { + await BeforeExecuteAsync(); + + var stopwatch = Stopwatch.StartNew(); + + try + { + await ExecuteAsync(); + } + catch + { + + } + finally + { + stopwatch.Stop(); + } + + await AfterExecuteAsync(); + } + + protected virtual Task BeforeExecuteAsync() + { + return Task.CompletedTask; + } + + protected abstract Task ExecuteAsync(); + + protected virtual Task AfterExecuteAsync() + { + return Task.CompletedTask; + } public virtual string GetDisplayText() { 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 7791b0ccea..0aa5b1d526 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 @@ -1,4 +1,4 @@ -using System.Threading; +using System.Threading.Tasks; namespace Volo.ClientSimulation.Scenarios { @@ -11,9 +11,9 @@ namespace Volo.ClientSimulation.Scenarios Duration = duration; } - public override void Run() + protected override Task ExecuteAsync() { - Thread.Sleep(Duration); + return Task.Delay(Duration); } public override string GetDisplayText() 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 5e2883013b..6d858d7dc0 100644 --- a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Simulation.cs +++ b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Simulation.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; +using Volo.Abp; using Volo.Abp.DependencyInjection; using Volo.ClientSimulation.Clients; using Volo.ClientSimulation.Scenarios; @@ -12,9 +13,7 @@ namespace Volo.ClientSimulation { public SimulationState State { get; private set; } - public List ActiveClients { get; } - - protected IClientFactory ClientFactory { get; } + public List Clients { get; } protected ClientSimulationOptions Options { get; } @@ -23,24 +22,25 @@ namespace Volo.ClientSimulation protected readonly object SyncObj = new object(); public Simulation( - IClientFactory clientFactory, IServiceScopeFactory serviceScopeFactory, IOptions options) { - ClientFactory = clientFactory; Options = options.Value; ServiceScope = serviceScopeFactory.CreateScope(); - ActiveClients = new List(); + + Clients = new List(); foreach (var scenarioConfiguration in Options.Scenarios) { for (int i = 0; i < scenarioConfiguration.ClientCount; i++) { - var scenario = (IScenario) ServiceScope.ServiceProvider.GetRequiredService( + var scenario = (Scenario) ServiceScope.ServiceProvider.GetRequiredService( scenarioConfiguration.ScenarioType ); - ActiveClients.Add(ClientFactory.Create(scenario)); + var client = ServiceScope.ServiceProvider.GetRequiredService(); + client.Initialize(scenario); + Clients.Add(client); } } } @@ -49,11 +49,16 @@ namespace Volo.ClientSimulation { lock (SyncObj) { + if (State != SimulationState.Stopped) + { + throw new UserFriendlyException($"Simulation should be stopped to be able to start. Current state is '{State}'."); + } + State = SimulationState.Starting; - foreach (var clientHandler in ActiveClients) + foreach (var client in Clients) { - clientHandler.Client.Start(); + client.Start(); } State = SimulationState.Started; @@ -64,11 +69,16 @@ namespace Volo.ClientSimulation { lock (SyncObj) { + if (State != SimulationState.Started) + { + throw new UserFriendlyException($"Simulation should be started to be able to stop. Current state is '{State}'."); + } + State = SimulationState.Stopping; - foreach (var activeClient in ActiveClients) + foreach (var client in Clients) { - activeClient.Client.Stop(); + client.Stop(); } State = SimulationState.Stopped; diff --git a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/SimulationState.cs b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/SimulationState.cs index 133748af1f..94961a111f 100644 --- a/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/SimulationState.cs +++ b/modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/SimulationState.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Volo.ClientSimulation +namespace Volo.ClientSimulation { public enum SimulationState {