Browse Source

Introduce SimulationSnapshot

pull/975/head
Halil ibrahim Kalkan 8 years ago
parent
commit
ad2609aab8
  1. 12
      modules/client-simulation/src/Volo.ClientSimulation.Web/Pages/ClientSimulation/SimulationArea.cshtml
  2. 6
      modules/client-simulation/src/Volo.ClientSimulation.Web/Pages/ClientSimulation/SimulationArea.cshtml.cs
  3. 33
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/Client.cs
  4. 8
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/IClient.cs
  5. 41
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/Scenario.cs
  6. 9
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Scenarios/ScenarioStep.cs
  7. 106
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Simulation.cs
  8. 13
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Snapshot/ClientSnapshot.cs
  9. 15
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Snapshot/ScenarioSnapshot.cs
  10. 10
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Snapshot/ScenarioStepSnapshot.cs
  11. 13
      modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Snapshot/SimulationSnapshot.cs

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

@ -8,18 +8,18 @@
@model Volo.ClientSimulation.Pages.ClientSimulation.SimulationAreaModel
<abp-alert alert-type="Primary">
<form class="d-inline" id="StartButtonForm" method="post" asp-page-handler="Start" data-ajaxForm="true">
<abp-button button-type="Primary" type="submit" disabled="@(Model.Simulation.State != SimulationState.Stopped)">Start</abp-button>
<abp-button button-type="Primary" type="submit" disabled="@(Model.Snapshot.State != SimulationState.Stopped)">Start</abp-button>
</form>
<form class="d-inline" id="StopButtonForm" method="post" asp-page-handler="Stop" data-ajaxForm="true">
<abp-button button-type="Primary" type="submit" disabled="@(Model.Simulation.State != SimulationState.Started)">Stop</abp-button>
<abp-button button-type="Primary" type="submit" disabled="@(Model.Snapshot.State != SimulationState.Started)">Stop</abp-button>
</form>
<span class="ml-3">
@Model.Simulation.State
@Model.Snapshot.State
</span>
</abp-alert>
<abp-card class="mt-3">
<abp-card-body>
@foreach (var client in Model.Simulation.Clients)
@foreach (var client in Model.Snapshot.Clients)
{
<span class="simulation-client simulation-client-@client.State.ToString().ToLowerInvariant()">
<span class="simulation-client-icon">
@ -37,12 +37,12 @@
}
</span>
<span class="simulation-client-scenario">
@client.Scenario.GetDisplayText()
@client.Scenario.DisplayText
</span>
<span class="simulation-client-scenario-current-step">
@if (client.State != ClientState.Stopped)
{
<text>| @client.Scenario.CurrentStep.GetDisplayText()</text>
<text>| @client.Scenario.CurrentStep.DisplayText</text>
}
</span>
</span>

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

@ -1,12 +1,15 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Volo.ClientSimulation.Snapshot;
namespace Volo.ClientSimulation.Pages.ClientSimulation
{
public class SimulationAreaModel : PageModel
{
public Simulation Simulation { get; }
public SimulationSnapshot Snapshot { get; private set; }
protected Simulation Simulation { get; }
public SimulationAreaModel(Simulation simulation)
{
@ -15,6 +18,7 @@ namespace Volo.ClientSimulation.Pages.ClientSimulation
public Task OnGetAsync()
{
Snapshot = Simulation.CreateSnapshot();
return Task.CompletedTask;
}

33
modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Clients/Client.cs

@ -1,13 +1,17 @@
using System.Threading;
using System;
using System.Threading;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Threading;
using Volo.ClientSimulation.Scenarios;
using Volo.ClientSimulation.Snapshot;
namespace Volo.ClientSimulation.Clients
{
public class Client : IClient, ITransientDependency
{
public event EventHandler Stopped;
public Scenario Scenario { get; private set; }
public ClientState State
@ -23,7 +27,15 @@ namespace Volo.ClientSimulation.Clients
public void Initialize(Scenario scenario)
{
Scenario = scenario;
lock (SyncLock)
{
if (State != ClientState.Stopped)
{
throw new UserFriendlyException($"Client should be stopped to be able to initialize it. Current state is '{State}'.");
}
Scenario = scenario;
}
}
public void Start()
@ -37,6 +49,7 @@ namespace Volo.ClientSimulation.Clients
State = ClientState.Running;
Scenario.Reset();
_thread = new Thread(Run);
_thread.Start();
}
@ -55,10 +68,20 @@ namespace Volo.ClientSimulation.Clients
}
}
private void Run()
public ClientSnapshot CreateSnapshot()
{
Scenario.Reset();
lock (SyncLock)
{
return new ClientSnapshot
{
State = State,
Scenario = Scenario.CreateSnapshot()
};
}
}
private void Run()
{
while (true)
{
lock (SyncLock)
@ -66,6 +89,8 @@ namespace Volo.ClientSimulation.Clients
if (State != ClientState.Running)
{
State = ClientState.Stopped;
_thread = null;
Stopped.InvokeSafely(this);
break;
}
}

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

@ -1,9 +1,13 @@
using Volo.ClientSimulation.Scenarios;
using System;
using Volo.ClientSimulation.Scenarios;
using Volo.ClientSimulation.Snapshot;
namespace Volo.ClientSimulation.Clients
{
public interface IClient
{
event EventHandler Stopped;
Scenario Scenario { get; }
ClientState State { get; }
@ -13,5 +17,7 @@ namespace Volo.ClientSimulation.Clients
void Start();
void Stop();
ClientSnapshot CreateSnapshot();
}
}

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

@ -1,29 +1,30 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.ClientSimulation.Snapshot;
namespace Volo.ClientSimulation.Scenarios
{
public abstract class Scenario : ITransientDependency
{
public IReadOnlyList<ScenarioStep> Steps => StepList.ToImmutableList();
protected List<ScenarioStep> StepList { get; }
protected List<ScenarioStep> Steps { get; }
public ScenarioStep CurrentStep
protected ScenarioStep CurrentStep
{
get
{
CheckStepCount();
return StepList[CurrentStepIndex];
return Steps[CurrentStepIndex];
}
}
public int CurrentStepIndex { get; protected set; }
protected int CurrentStepIndex { get; set; }
protected Scenario()
{
StepList = new List<ScenarioStep>();
Steps = new List<ScenarioStep>();
}
public virtual string GetDisplayText()
@ -37,11 +38,11 @@ namespace Volo.ClientSimulation.Scenarios
{
CheckStepCount();
await StepList[CurrentStepIndex].RunAsync();
await Steps[CurrentStepIndex].RunAsync();
CurrentStepIndex++;
if (CurrentStepIndex >= StepList.Count)
if (CurrentStepIndex >= Steps.Count)
{
CurrentStepIndex = 0;
}
@ -52,19 +53,29 @@ namespace Volo.ClientSimulation.Scenarios
CurrentStepIndex = 0;
}
public ScenarioSnapshot CreateSnapshot()
{
return new ScenarioSnapshot
{
DisplayText = GetDisplayText(),
Steps = Steps.Select(s => s.CreateSnapshot()).ToList(),
CurrentStep = CurrentStep.CreateSnapshot()
};
}
protected void AddStep(ScenarioStep step)
{
Steps.Add(step);
}
private void CheckStepCount()
{
if (StepList.Count <= 0)
if (Steps.Count <= 0)
{
throw new ApplicationException(
$"No Steps added to the scenario '{GetDisplayText()}'"
);
}
}
protected void AddStep(ScenarioStep step)
{
StepList.Add(step);
}
}
}

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

@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Volo.ClientSimulation.Snapshot;
namespace Volo.ClientSimulation.Scenarios
{
@ -46,5 +47,13 @@ namespace Volo.ClientSimulation.Scenarios
.Name
.RemovePostFix(nameof(ScenarioStep));
}
public ScenarioStepSnapshot CreateSnapshot()
{
return new ScenarioStepSnapshot
{
DisplayText = GetDisplayText()
};
}
}
}

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

@ -1,23 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
using Volo.ClientSimulation.Clients;
using Volo.ClientSimulation.Scenarios;
using Volo.ClientSimulation.Snapshot;
namespace Volo.ClientSimulation
{
public class Simulation : ISingletonDependency, IDisposable
{
public ILogger<Simulation> Logger { get; set; }
public SimulationState State { get; private set; }
public List<IClient> Clients { get; }
protected ClientSimulationOptions Options { get; }
protected IServiceScope ServiceScope { get; }
protected IServiceScopeFactory ServiceScopeFactory { get; }
protected IServiceScope ServiceScope { get; private set; }
protected readonly object SyncObj = new object();
@ -25,27 +31,15 @@ namespace Volo.ClientSimulation
IServiceScopeFactory serviceScopeFactory,
IOptions<ClientSimulationOptions> options)
{
ServiceScopeFactory = serviceScopeFactory;
Options = options.Value;
ServiceScope = serviceScopeFactory.CreateScope();
Clients = new List<IClient>();
Logger = NullLogger<Simulation>.Instance;
foreach (var scenarioConfiguration in Options.Scenarios)
{
for (int i = 0; i < scenarioConfiguration.ClientCount; i++)
{
var scenario = (Scenario) ServiceScope.ServiceProvider.GetRequiredService(
scenarioConfiguration.ScenarioType
);
var client = ServiceScope.ServiceProvider.GetRequiredService<IClient>();
client.Initialize(scenario);
Clients.Add(client);
}
}
Clients = new List<IClient>();
}
public void Start()
public virtual void Start()
{
lock (SyncObj)
{
@ -56,16 +50,42 @@ namespace Volo.ClientSimulation
State = SimulationState.Starting;
foreach (var client in Clients)
try
{
client.Start();
DisposeResources();
ServiceScope = ServiceScopeFactory.CreateScope();
foreach (var scenarioConfiguration in Options.Scenarios)
{
for (int i = 0; i < scenarioConfiguration.ClientCount; i++)
{
var scenario = (Scenario)ServiceScope.ServiceProvider.GetRequiredService(
scenarioConfiguration.ScenarioType
);
var client = ServiceScope.ServiceProvider.GetRequiredService<IClient>();
client.Stopped += Client_OnStopped;
client.Initialize(scenario);
Clients.Add(client);
}
}
foreach (var client in Clients)
{
client.Start();
}
State = SimulationState.Started;
}
catch(Exception ex)
{
Logger.LogException(ex);
State = SimulationState.Stopped;
}
State = SimulationState.Started;
}
}
public void Stop()
public virtual void Stop()
{
lock (SyncObj)
{
@ -80,14 +100,48 @@ namespace Volo.ClientSimulation
{
client.Stop();
}
}
}
State = SimulationState.Stopped;
public virtual SimulationSnapshot CreateSnapshot()
{
lock (SyncObj)
{
return new SimulationSnapshot
{
State = State,
Clients = Clients
.Select(c => c.CreateSnapshot())
.ToList()
};
}
}
public virtual void Dispose()
{
DisposeResources();
}
protected virtual void Client_OnStopped(object sender, EventArgs e)
{
lock (SyncObj)
{
if (Clients.All(c => c.State == ClientState.Stopped))
{
OnStopped();
}
}
}
public void Dispose()
private void OnStopped()
{
State = SimulationState.Stopped;
}
private void DisposeResources()
{
ServiceScope.Dispose();
Clients.Clear();
ServiceScope?.Dispose();
}
}
}

13
modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Snapshot/ClientSnapshot.cs

@ -0,0 +1,13 @@
using System;
using Volo.ClientSimulation.Clients;
namespace Volo.ClientSimulation.Snapshot
{
[Serializable]
public class ClientSnapshot
{
public ClientState State { get; set; }
public ScenarioSnapshot Scenario { get; set; }
}
}

15
modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Snapshot/ScenarioSnapshot.cs

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
namespace Volo.ClientSimulation.Snapshot
{
[Serializable]
public class ScenarioSnapshot
{
public string DisplayText { get; set; }
public List<ScenarioStepSnapshot> Steps { get; set; }
public ScenarioStepSnapshot CurrentStep { get; set; }
}
}

10
modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Snapshot/ScenarioStepSnapshot.cs

@ -0,0 +1,10 @@
using System;
namespace Volo.ClientSimulation.Snapshot
{
[Serializable]
public class ScenarioStepSnapshot
{
public string DisplayText { get; set; }
}
}

13
modules/client-simulation/src/Volo.ClientSimulation/Volo/ClientSimulation/Snapshot/SimulationSnapshot.cs

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
namespace Volo.ClientSimulation.Snapshot
{
[Serializable]
public class SimulationSnapshot
{
public SimulationState State { get; set; }
public List<ClientSnapshot> Clients { get; set; }
}
}
Loading…
Cancel
Save