mirror of https://github.com/abpframework/abp.git
csharpabpc-sharpframeworkblazoraspnet-coredotnet-coreaspnetcorearchitecturesaasdomain-driven-designangularmulti-tenancy
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
4.1 KiB
155 lines
4.1 KiB
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 => _state;
|
|
private set => _state = value;
|
|
}
|
|
private volatile SimulationState _state;
|
|
|
|
public List<IClient> Clients { get; }
|
|
|
|
protected ClientSimulationOptions Options { get; }
|
|
protected IServiceScopeFactory ServiceScopeFactory { get; }
|
|
protected IServiceScope ServiceScope { get; private set; }
|
|
protected object SyncObj { get; } = new object();
|
|
|
|
public Simulation(
|
|
IServiceScopeFactory serviceScopeFactory,
|
|
IOptions<ClientSimulationOptions> options)
|
|
{
|
|
ServiceScopeFactory = serviceScopeFactory;
|
|
Options = options.Value;
|
|
|
|
Logger = NullLogger<Simulation>.Instance;
|
|
|
|
Clients = new List<IClient>();
|
|
}
|
|
|
|
public virtual void Start()
|
|
{
|
|
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;
|
|
|
|
try
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
public virtual void Stop()
|
|
{
|
|
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 client in Clients)
|
|
{
|
|
client.Stop();
|
|
}
|
|
}
|
|
}
|
|
|
|
public virtual SimulationSnapshot CreateSnapshot()
|
|
{
|
|
SimulationSnapshot snapshot;
|
|
|
|
lock (SyncObj)
|
|
{
|
|
snapshot = new SimulationSnapshot
|
|
{
|
|
State = State,
|
|
Clients = Clients
|
|
.Select(c => c.CreateSnapshot())
|
|
.ToList()
|
|
};
|
|
}
|
|
|
|
snapshot.CreateSummaries();
|
|
|
|
return snapshot;
|
|
}
|
|
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnStopped()
|
|
{
|
|
State = SimulationState.Stopped;
|
|
}
|
|
|
|
private void DisposeResources()
|
|
{
|
|
Clients.Clear();
|
|
ServiceScope?.Dispose();
|
|
}
|
|
}
|
|
|