Browse Source

Added scenario concept

pull/975/head
Halil ibrahim Kalkan 8 years ago
parent
commit
3948223b52
  1. 2
      framework/src/Volo.Abp.Core/Volo/Abp/RandomHelper.cs
  2. 8
      utils/client-simulation/src/Volo.ClientSimulation.Web/Pages/Index.cshtml
  3. 7
      utils/client-simulation/src/Volo.ClientSimulation.Web/Pages/SimulationArea.cshtml
  4. 5
      utils/client-simulation/src/Volo.ClientSimulation.Web/Pages/SimulationArea.css
  5. 1
      utils/client-simulation/src/Volo.ClientSimulation.Web/Pages/SimulationArea.min.css
  6. 6
      utils/client-simulation/src/Volo.ClientSimulation.Web/Pages/SimulationArea.scss
  7. 8
      utils/client-simulation/src/Volo.ClientSimulation.Web/Volo.ClientSimulation.Web.csproj
  8. 6
      utils/client-simulation/src/Volo.ClientSimulation.Web/compilerconfig.json
  9. 63
      utils/client-simulation/src/Volo.ClientSimulation.Web/compilerconfig.json.defaults
  10. 10
      utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/ClientSimulationModule.cs
  11. 15
      utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/ClientSimulationOptions.cs
  12. 46
      utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/Client.cs
  13. 3
      utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IClient.cs
  14. 20
      utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IClientFactory.cs
  15. 24
      utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IDisposableClientHandler.cs
  16. 122
      utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/Scenario.cs
  17. 37
      utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Simulation.cs

2
framework/src/Volo.Abp.Core/Volo/Abp/RandomHelper.cs

@ -77,7 +77,7 @@ namespace Volo.Abp
/// </summary>
/// <typeparam name="T">Type of the objects</typeparam>
/// <param name="list">List of object to select a random one</param>
public static T GetRandomOf<T>([NotNull] IList<T> list)
public static T GetRandomOfList<T>([NotNull] IList<T> list)
{
Check.NotNullOrEmpty(list, nameof(list));

8
utils/client-simulation/src/Volo.ClientSimulation.Web/Pages/Index.cshtml

@ -1,7 +1,11 @@
@page
@model Volo.ClientSimulation.Web.Pages.IndexModel
@section scripts
{
@section styles {
<abp-style-bundle>
<abp-style src="/Pages/SimulationArea.min.css" />
</abp-style-bundle>
}
@section scripts {
<abp-script-bundle>
<abp-script src="/Pages/SimulationArea.js" />
<abp-script src="/Pages/Index.js" />

7
utils/client-simulation/src/Volo.ClientSimulation.Web/Pages/SimulationArea.cshtml

@ -17,6 +17,11 @@
</abp-alert>
<abp-card class="mt-3">
<abp-card-body>
<span>Active client count: @Model.Simulation.ActiveClients.Count</span>
@foreach (var clientHandler in Model.Simulation.ActiveClients)
{
<span class="simulation-client">
[@clientHandler.Client.State] @clientHandler.Client.Scenario.GetDisplayText(): @clientHandler.Client.Scenario.CurrentStep.GetDisplayText()
</span>
}
</abp-card-body>
</abp-card>

5
utils/client-simulation/src/Volo.ClientSimulation.Web/Pages/SimulationArea.css

@ -0,0 +1,5 @@
.simulation-client {
border: 1px solid #008000;
background-color: #d6ffce;
margin: 3px;
padding: 5px; }

1
utils/client-simulation/src/Volo.ClientSimulation.Web/Pages/SimulationArea.min.css

@ -0,0 +1 @@
.simulation-client{border:1px solid #008000;background-color:#d6ffce;margin:3px;padding:5px;}

6
utils/client-simulation/src/Volo.ClientSimulation.Web/Pages/SimulationArea.scss

@ -0,0 +1,6 @@
.simulation-client {
border: 1px solid #008000;
background-color: #d6ffce;
margin: 3px;
padding: 5px;
}

8
utils/client-simulation/src/Volo.ClientSimulation.Web/Volo.ClientSimulation.Web.csproj

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

6
utils/client-simulation/src/Volo.ClientSimulation.Web/compilerconfig.json

@ -0,0 +1,6 @@
[
{
"outputFile": "Pages/SimulationArea.css",
"inputFile": "Pages/SimulationArea.scss"
}
]

63
utils/client-simulation/src/Volo.ClientSimulation.Web/compilerconfig.json.defaults

@ -0,0 +1,63 @@
{
"compilers": {
"less": {
"autoPrefix": "",
"cssComb": "none",
"ieCompat": true,
"strictMath": false,
"strictUnits": false,
"relativeUrls": true,
"rootPath": "",
"sourceMapRoot": "",
"sourceMapBasePath": "",
"sourceMap": false
},
"sass": {
"autoPrefix": "",
"includePath": "",
"indentType": "space",
"indentWidth": 2,
"outputStyle": "nested",
"Precision": 5,
"relativeUrls": true,
"sourceMapRoot": "",
"lineFeed": "",
"sourceMap": false
},
"stylus": {
"sourceMap": false
},
"babel": {
"sourceMap": false
},
"coffeescript": {
"bare": false,
"runtimeMode": "node",
"sourceMap": false
},
"handlebars": {
"root": "",
"noBOM": false,
"name": "",
"namespace": "",
"knownHelpersOnly": false,
"forcePartial": false,
"knownHelpers": [],
"commonjs": "",
"amd": false,
"sourceMap": false
}
},
"minifiers": {
"css": {
"enabled": true,
"termSemicolons": true,
"gzip": false
},
"javascript": {
"enabled": true,
"termSemicolons": true,
"gzip": false
}
}
}

10
utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/ClientSimulationModule.cs

@ -1,5 +1,6 @@
using Volo.Abp.Http.Client.IdentityModel;
using Volo.Abp.Modularity;
using Volo.ClientSimulation.Scenarios;
namespace Volo.ClientSimulation
{
@ -8,6 +9,13 @@ namespace Volo.ClientSimulation
)]
public class ClientSimulationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
//TODO: Temporary add a DemoScenario, remove later
Configure<ClientSimulationOptions>(options =>
{
options.Scenarios.Add(new DemoScenario());
});
}
}
}

15
utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/ClientSimulationOptions.cs

@ -0,0 +1,15 @@
using System.Collections.Generic;
using Volo.ClientSimulation.Scenarios;
namespace Volo.ClientSimulation
{
public class ClientSimulationOptions
{
public List<IScenario> Scenarios { get; }
public ClientSimulationOptions()
{
Scenarios = new List<IScenario>();
}
}
}

46
utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/Client.cs

@ -1,45 +1,65 @@
using System;
using System.Threading;
using Volo.Abp.DependencyInjection;
using Volo.ClientSimulation.Scenarios;
namespace Volo.ClientSimulation.Clients
{
public class Client : IClient, ITransientDependency
public class Client : IClient
{
public IScenario Scenario { get; }
public event EventHandler Stopped;
public ClientState State { get; private set; }
public ClientState State
{
get => _state;
private set => _state = value;
}
private volatile ClientState _state;
private Thread _thread;
public Client()
protected readonly object SyncLock = new object();
public Client(IScenario scenario)
{
Scenario = scenario;
}
public void Start()
{
if (State != ClientState.Stopped)
lock (SyncLock)
{
throw new ApplicationException("State is not stopped. It is " + State);
}
if (State != ClientState.Stopped)
{
throw new ApplicationException("State is not stopped. It is " + State);
}
State = ClientState.Running;
State = ClientState.Running;
_thread = new Thread(Run);
_thread.Start();
_thread = new Thread(Run);
_thread.Start();
}
}
public void Stop()
{
State = ClientState.Stopping;
lock (SyncLock)
{
if (State != ClientState.Running)
{
return;
}
State = ClientState.Stopping;
}
}
private void Run()
{
while (State == ClientState.Running)
{
Thread.Sleep(1);
Scenario.Proceed();
}
State = ClientState.Stopped;

3
utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IClient.cs

@ -1,9 +1,12 @@
using System;
using Volo.ClientSimulation.Scenarios;
namespace Volo.ClientSimulation.Clients
{
public interface IClient
{
IScenario Scenario { get; }
event EventHandler Stopped;
ClientState State { get; }

20
utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IClientFactory.cs

@ -0,0 +1,20 @@
using System.Collections.Generic;
using System.Text;
using Volo.Abp.DependencyInjection;
using Volo.ClientSimulation.Scenarios;
namespace Volo.ClientSimulation.Clients
{
public interface IClientFactory
{
IDisposableClientHandler Create(IScenario scenario);
}
public class DefaultClientFactory : IClientFactory, ISingletonDependency
{
public IDisposableClientHandler Create(IScenario scenario)
{
return new DisposableClientHandler(new Client(scenario));
}
}
}

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

@ -0,0 +1,24 @@
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()
{
}
}
}

122
utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/Scenario.cs

@ -0,0 +1,122 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Text;
using System.Threading;
namespace Volo.ClientSimulation.Scenarios
{
public abstract class Scenario : IScenario
{
public IReadOnlyList<IScenarioStep> Steps => StepList.ToImmutableList();
protected List<IScenarioStep> StepList { get; }
public IScenarioStep CurrentStep
{
get
{
CheckStepCount();
return StepList[CurrentStepIndex];
}
}
public int CurrentStepIndex { get; protected set; }
protected Scenario()
{
StepList = new List<IScenarioStep>();
}
public virtual string GetDisplayText()
{
return GetType()
.Name
.RemovePostFix(nameof(Scenario));
}
public virtual void Proceed()
{
CheckStepCount();
StepList[CurrentStepIndex].Run();
CurrentStepIndex++;
if (CurrentStepIndex >= StepList.Count)
{
CurrentStepIndex = 0;
}
}
private void CheckStepCount()
{
if (StepList.Count <= 0)
{
throw new ApplicationException(
$"No Steps defined for the scenario '{GetDisplayText()}'"
);
}
}
protected void AddStep(IScenarioStep step)
{
StepList.Add(step);
}
}
public interface IScenario
{
IReadOnlyList<IScenarioStep> Steps { get; }
IScenarioStep CurrentStep { get; }
int CurrentStepIndex { get; }
string GetDisplayText();
void Proceed();
}
public interface IScenarioStep
{
void Run();
string GetDisplayText();
}
public abstract class ScenarioStep : IScenarioStep
{
public abstract void Run();
public virtual string GetDisplayText()
{
return GetType()
.Name
.RemovePostFix(nameof(ScenarioStep));
}
}
public class DemoScenario : Scenario
{
public DemoScenario()
{
AddStep(new SleepScenarioStep());
AddStep(new SleepScenarioStep(3000));
AddStep(new SleepScenarioStep());
}
}
public class SleepScenarioStep : ScenarioStep
{
public int Duration { get; }
public SleepScenarioStep(int duration = 1000)
{
Duration = duration;
}
public override void Run()
{
Thread.Sleep(Duration);
}
}
}

37
utils/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Simulation.cs

@ -1,12 +1,13 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
using Volo.ClientSimulation.Clients;
namespace Volo.ClientSimulation
{
public class Simulation : ISingletonDependency, IDisposable
public class Simulation : ISingletonDependency
{
public GlobalOptions GlobalOptions { get; }
@ -14,17 +15,21 @@ namespace Volo.ClientSimulation
public SimulationState State { get; private set; }
public List<IClient> ActiveClients { get; }
public List<IDisposableClientHandler> ActiveClients { get; }
private readonly IServiceScope _serviceScope;
protected IClientFactory ClientFactory { get; }
protected ClientSimulationOptions Options { get; }
public Simulation(
GlobalOptions globalOptions,
IServiceScopeFactory serviceScopeFactory)
GlobalOptions globalOptions,
IClientFactory clientFactory,
IOptions<ClientSimulationOptions> options)
{
_serviceScope = serviceScopeFactory.CreateScope();
GlobalOptions = globalOptions;
ActiveClients = new List<IClient>();
ClientFactory = clientFactory;
Options = options.Value;
ActiveClients = new List<IDisposableClientHandler>();
}
public void Start()
@ -39,13 +44,14 @@ namespace Volo.ClientSimulation
for (int i = 0; i < CurrentOptions.MaxClientCount; i++)
{
ActiveClients.Add(_serviceScope.ServiceProvider.GetRequiredService<IClient>());
var selectedScenario = RandomHelper.GetRandomOfList(Options.Scenarios);
ActiveClients.Add(ClientFactory.Create(selectedScenario));
}
foreach (var activeClient in ActiveClients)
{
activeClient.Stopped += ActiveClientOnStopped;
activeClient.Start();
activeClient.Client.Stopped += ActiveClientOnStopped;
activeClient.Client.Start();
}
}
@ -60,7 +66,7 @@ namespace Volo.ClientSimulation
{
foreach (var activeClient in ActiveClients)
{
activeClient.Stop();
activeClient.Client.Stop();
}
}
@ -73,13 +79,8 @@ namespace Volo.ClientSimulation
lock (ActiveClients)
{
ActiveClients.Remove(client);
ActiveClients.RemoveAll(c => c.Client == client);
}
}
public void Dispose()
{
_serviceScope.Dispose();
}
}
}

Loading…
Cancel
Save