mirror of https://github.com/abpframework/abp.git
8 changed files with 160 additions and 10 deletions
@ -0,0 +1,49 @@ |
|||||
|
using System; |
||||
|
using System.Threading; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.ClientSimulation.Clients |
||||
|
{ |
||||
|
public class Client : IClient, ITransientDependency |
||||
|
{ |
||||
|
public event EventHandler Stopped; |
||||
|
|
||||
|
public ClientState State { get; private set; } |
||||
|
|
||||
|
private Thread _thread; |
||||
|
|
||||
|
public Client() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void Start() |
||||
|
{ |
||||
|
if (State != ClientState.Stopped) |
||||
|
{ |
||||
|
throw new ApplicationException("State is not stopped. It is " + State); |
||||
|
} |
||||
|
|
||||
|
State = ClientState.Running; |
||||
|
|
||||
|
_thread = new Thread(Run); |
||||
|
_thread.Start(); |
||||
|
} |
||||
|
|
||||
|
public void Stop() |
||||
|
{ |
||||
|
State = ClientState.Stopping; |
||||
|
} |
||||
|
|
||||
|
private void Run() |
||||
|
{ |
||||
|
while (State == ClientState.Running) |
||||
|
{ |
||||
|
Thread.Sleep(1); |
||||
|
} |
||||
|
|
||||
|
State = ClientState.Stopped; |
||||
|
Stopped.InvokeSafely(this); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
namespace Volo.ClientSimulation.Clients |
||||
|
{ |
||||
|
public enum ClientState |
||||
|
{ |
||||
|
Stopped, |
||||
|
Running, |
||||
|
Stopping |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.ClientSimulation.Clients |
||||
|
{ |
||||
|
public interface IClient |
||||
|
{ |
||||
|
event EventHandler Stopped; |
||||
|
|
||||
|
ClientState State { get; } |
||||
|
|
||||
|
void Start(); |
||||
|
|
||||
|
void Stop(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.ClientSimulation |
||||
|
{ |
||||
|
public class GlobalOptions : ISingletonDependency |
||||
|
{ |
||||
|
public int MaxClientCount { get; set; } = 2; |
||||
|
|
||||
|
public GlobalOptions Clone() |
||||
|
{ |
||||
|
return new GlobalOptions |
||||
|
{ |
||||
|
MaxClientCount = MaxClientCount |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,26 +1,85 @@ |
|||||
using System.Threading.Tasks; |
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
using Volo.Abp.DependencyInjection; |
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.ClientSimulation.Clients; |
||||
|
|
||||
namespace Volo.ClientSimulation |
namespace Volo.ClientSimulation |
||||
{ |
{ |
||||
public class Simulation : ISingletonDependency |
public class Simulation : ISingletonDependency, IDisposable |
||||
{ |
{ |
||||
|
public GlobalOptions GlobalOptions { get; } |
||||
|
|
||||
|
public GlobalOptions CurrentOptions { get; private set; } |
||||
|
|
||||
public SimulationState State { get; private set; } |
public SimulationState State { get; private set; } |
||||
|
|
||||
public Task StartAsync() |
public List<IClient> ActiveClients { get; } |
||||
|
|
||||
|
private readonly IServiceScope _serviceScope; |
||||
|
|
||||
|
public Simulation( |
||||
|
GlobalOptions globalOptions, |
||||
|
IServiceScopeFactory serviceScopeFactory) |
||||
|
{ |
||||
|
_serviceScope = serviceScopeFactory.CreateScope(); |
||||
|
GlobalOptions = globalOptions; |
||||
|
ActiveClients = new List<IClient>(); |
||||
|
} |
||||
|
|
||||
|
public void Start() |
||||
{ |
{ |
||||
State = SimulationState.Starting; |
State = SimulationState.Starting; |
||||
State = SimulationState.Started; |
|
||||
|
|
||||
return Task.CompletedTask; |
CurrentOptions = GlobalOptions.Clone(); |
||||
|
|
||||
|
lock (ActiveClients) |
||||
|
{ |
||||
|
ActiveClients.Clear(); |
||||
|
|
||||
|
for (int i = 0; i < CurrentOptions.MaxClientCount; i++) |
||||
|
{ |
||||
|
ActiveClients.Add(_serviceScope.ServiceProvider.GetRequiredService<IClient>()); |
||||
|
} |
||||
|
|
||||
|
foreach (var activeClient in ActiveClients) |
||||
|
{ |
||||
|
activeClient.Stopped += ActiveClientOnStopped; |
||||
|
activeClient.Start(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
State = SimulationState.Started; |
||||
} |
} |
||||
|
|
||||
public Task StopAsync() |
public void Stop() |
||||
{ |
{ |
||||
State = SimulationState.Stopping; |
State = SimulationState.Stopping; |
||||
|
|
||||
|
lock (ActiveClients) |
||||
|
{ |
||||
|
foreach (var activeClient in ActiveClients) |
||||
|
{ |
||||
|
activeClient.Stop(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
State = SimulationState.Stopped; |
State = SimulationState.Stopped; |
||||
|
} |
||||
|
|
||||
return Task.CompletedTask; |
private void ActiveClientOnStopped(object sender, EventArgs e) |
||||
|
{ |
||||
|
var client = (IClient) sender; |
||||
|
|
||||
|
lock (ActiveClients) |
||||
|
{ |
||||
|
ActiveClients.Remove(client); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
_serviceScope.Dispose(); |
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
|||||
Loading…
Reference in new issue