Browse Source

Simulation refactor

pull/975/head
Halil ibrahim Kalkan 8 years ago
parent
commit
437cec92ac
  1. 16
      modules/client-simulation/src/Volo.ClientSimulation.Web/Pages/ClientSimulation/SimulationArea.cshtml
  2. 31
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/Client.cs
  3. 13
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/DefaultClientFactory.cs
  4. 4
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IClient.cs
  5. 9
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IClientFactory.cs
  6. 24
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IDisposableClientHandler.cs
  7. 17
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/IScenario.cs
  8. 9
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/IScenarioStep.cs
  9. 22
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/Scenario.cs
  10. 38
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/ScenarioStep.cs
  11. 6
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/SleepScenarioStep.cs
  12. 34
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Simulation.cs
  13. 6
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/SimulationState.cs

16
modules/client-simulation/src/Volo.ClientSimulation.Web/Pages/ClientSimulation/SimulationArea.cshtml

@ -19,30 +19,30 @@
</abp-alert> </abp-alert>
<abp-card class="mt-3"> <abp-card class="mt-3">
<abp-card-body> <abp-card-body>
@foreach (var clientHandler in Model.Simulation.ActiveClients) @foreach (var client in Model.Simulation.Clients)
{ {
<span class="simulation-client simulation-client-@clientHandler.Client.State.ToString().ToLowerInvariant()"> <span class="simulation-client simulation-client-@client.State.ToString().ToLowerInvariant()">
<span class="simulation-client-icon"> <span class="simulation-client-icon">
@if (clientHandler.Client.State == ClientState.Running) @if (client.State == ClientState.Running)
{ {
<i class="fa fa-play"></i> <i class="fa fa-play"></i>
} }
else if (clientHandler.Client.State == ClientState.Stopping) else if (client.State == ClientState.Stopping)
{ {
<i class="fa fa-eject"></i> <i class="fa fa-eject"></i>
} }
else if (clientHandler.Client.State == ClientState.Stopped) else if (client.State == ClientState.Stopped)
{ {
<i class="fa fa-stop"></i> <i class="fa fa-stop"></i>
} }
</span> </span>
<span class="simulation-client-scenario"> <span class="simulation-client-scenario">
@clientHandler.Client.Scenario.GetDisplayText() @client.Scenario.GetDisplayText()
</span> </span>
<span class="simulation-client-scenario-current-step"> <span class="simulation-client-scenario-current-step">
@if (clientHandler.Client.State != ClientState.Stopped) @if (client.State != ClientState.Stopped)
{ {
<text>| @clientHandler.Client.Scenario.CurrentStep.GetDisplayText()</text> <text>| @client.Scenario.CurrentStep.GetDisplayText()</text>
} }
</span> </span>
</span> </span>

31
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; using Volo.ClientSimulation.Scenarios;
namespace Volo.ClientSimulation.Clients 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 public ClientState State
{ {
@ -19,7 +21,7 @@ namespace Volo.ClientSimulation.Clients
protected readonly object SyncLock = new object(); protected readonly object SyncLock = new object();
public Client(IScenario scenario) public void Initialize(Scenario scenario)
{ {
Scenario = scenario; Scenario = scenario;
} }
@ -30,7 +32,7 @@ namespace Volo.ClientSimulation.Clients
{ {
if (State != ClientState.Stopped) 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; State = ClientState.Running;
@ -55,12 +57,21 @@ namespace Volo.ClientSimulation.Clients
private void Run() 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());
}
} }
} }
} }

13
modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/DefaultClientFactory.cs

@ -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));
}
}
}

4
modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IClient.cs

@ -4,10 +4,12 @@ namespace Volo.ClientSimulation.Clients
{ {
public interface IClient public interface IClient
{ {
IScenario Scenario { get; } Scenario Scenario { get; }
ClientState State { get; } ClientState State { get; }
void Initialize(Scenario scenario);
void Start(); void Start();
void Stop(); void Stop();

9
modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IClientFactory.cs

@ -1,9 +0,0 @@
using Volo.ClientSimulation.Scenarios;
namespace Volo.ClientSimulation.Clients
{
public interface IClientFactory
{
IDisposableClientHandler Create(IScenario scenario);
}
}

24
modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IDisposableClientHandler.cs

@ -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()
{
}
}
}

17
modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/IScenario.cs

@ -1,17 +0,0 @@
using System.Collections.Generic;
namespace Volo.ClientSimulation.Scenarios
{
public interface IScenario
{
IReadOnlyList<IScenarioStep> Steps { get; }
IScenarioStep CurrentStep { get; }
int CurrentStepIndex { get; }
string GetDisplayText();
void Proceed();
}
}

9
modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/IScenarioStep.cs

@ -1,9 +0,0 @@
namespace Volo.ClientSimulation.Scenarios
{
public interface IScenarioStep
{
void Run();
string GetDisplayText();
}
}

22
modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/Scenario.cs

@ -1,16 +1,17 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.ClientSimulation.Scenarios namespace Volo.ClientSimulation.Scenarios
{ {
public abstract class Scenario : IScenario, ITransientDependency public abstract class Scenario : ITransientDependency
{ {
public IReadOnlyList<IScenarioStep> Steps => StepList.ToImmutableList(); public IReadOnlyList<ScenarioStep> Steps => StepList.ToImmutableList();
protected List<IScenarioStep> StepList { get; } protected List<ScenarioStep> StepList { get; }
public IScenarioStep CurrentStep public ScenarioStep CurrentStep
{ {
get get
{ {
@ -22,7 +23,7 @@ namespace Volo.ClientSimulation.Scenarios
protected Scenario() protected Scenario()
{ {
StepList = new List<IScenarioStep>(); StepList = new List<ScenarioStep>();
} }
public virtual string GetDisplayText() public virtual string GetDisplayText()
@ -32,11 +33,11 @@ namespace Volo.ClientSimulation.Scenarios
.RemovePostFix(nameof(Scenario)); .RemovePostFix(nameof(Scenario));
} }
public virtual void Proceed() public virtual async Task ProceedAsync()
{ {
CheckStepCount(); CheckStepCount();
StepList[CurrentStepIndex].Run(); await StepList[CurrentStepIndex].RunAsync();
CurrentStepIndex++; CurrentStepIndex++;
@ -46,6 +47,11 @@ namespace Volo.ClientSimulation.Scenarios
} }
} }
public void Reset()
{
CurrentStepIndex = 0;
}
private void CheckStepCount() private void CheckStepCount()
{ {
if (StepList.Count <= 0) 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); StepList.Add(step);
} }

38
modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/ScenarioStep.cs

@ -1,10 +1,44 @@
using System; using System;
using System.Diagnostics;
using System.Threading.Tasks;
namespace Volo.ClientSimulation.Scenarios 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() public virtual string GetDisplayText()
{ {

6
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 namespace Volo.ClientSimulation.Scenarios
{ {
@ -11,9 +11,9 @@ namespace Volo.ClientSimulation.Scenarios
Duration = duration; Duration = duration;
} }
public override void Run() protected override Task ExecuteAsync()
{ {
Thread.Sleep(Duration); return Task.Delay(Duration);
} }
public override string GetDisplayText() public override string GetDisplayText()

34
modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Simulation.cs

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.ClientSimulation.Clients; using Volo.ClientSimulation.Clients;
using Volo.ClientSimulation.Scenarios; using Volo.ClientSimulation.Scenarios;
@ -12,9 +13,7 @@ namespace Volo.ClientSimulation
{ {
public SimulationState State { get; private set; } public SimulationState State { get; private set; }
public List<IDisposableClientHandler> ActiveClients { get; } public List<IClient> Clients { get; }
protected IClientFactory ClientFactory { get; }
protected ClientSimulationOptions Options { get; } protected ClientSimulationOptions Options { get; }
@ -23,24 +22,25 @@ namespace Volo.ClientSimulation
protected readonly object SyncObj = new object(); protected readonly object SyncObj = new object();
public Simulation( public Simulation(
IClientFactory clientFactory,
IServiceScopeFactory serviceScopeFactory, IServiceScopeFactory serviceScopeFactory,
IOptions<ClientSimulationOptions> options) IOptions<ClientSimulationOptions> options)
{ {
ClientFactory = clientFactory;
Options = options.Value; Options = options.Value;
ServiceScope = serviceScopeFactory.CreateScope(); ServiceScope = serviceScopeFactory.CreateScope();
ActiveClients = new List<IDisposableClientHandler>();
Clients = new List<IClient>();
foreach (var scenarioConfiguration in Options.Scenarios) foreach (var scenarioConfiguration in Options.Scenarios)
{ {
for (int i = 0; i < scenarioConfiguration.ClientCount; i++) for (int i = 0; i < scenarioConfiguration.ClientCount; i++)
{ {
var scenario = (IScenario) ServiceScope.ServiceProvider.GetRequiredService( var scenario = (Scenario) ServiceScope.ServiceProvider.GetRequiredService(
scenarioConfiguration.ScenarioType scenarioConfiguration.ScenarioType
); );
ActiveClients.Add(ClientFactory.Create(scenario)); var client = ServiceScope.ServiceProvider.GetRequiredService<IClient>();
client.Initialize(scenario);
Clients.Add(client);
} }
} }
} }
@ -49,11 +49,16 @@ namespace Volo.ClientSimulation
{ {
lock (SyncObj) 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; State = SimulationState.Starting;
foreach (var clientHandler in ActiveClients) foreach (var client in Clients)
{ {
clientHandler.Client.Start(); client.Start();
} }
State = SimulationState.Started; State = SimulationState.Started;
@ -64,11 +69,16 @@ namespace Volo.ClientSimulation
{ {
lock (SyncObj) 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; State = SimulationState.Stopping;
foreach (var activeClient in ActiveClients) foreach (var client in Clients)
{ {
activeClient.Client.Stop(); client.Stop();
} }
State = SimulationState.Stopped; State = SimulationState.Stopped;

6
modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/SimulationState.cs

@ -1,8 +1,4 @@
using System; namespace Volo.ClientSimulation
using System.Collections.Generic;
using System.Text;
namespace Volo.ClientSimulation
{ {
public enum SimulationState public enum SimulationState
{ {

Loading…
Cancel
Save