SEBWIN-220: Introduced timeout for startup and shutdown of BaseHost.
This commit is contained in:
parent
86d6949a6f
commit
c8001e85f6
10 changed files with 31 additions and 19 deletions
|
@ -40,7 +40,7 @@ namespace SafeExamBrowser.Client.UnitTests.Communication
|
|||
|
||||
hostObjectFactory.Setup(f => f.CreateObject(It.IsAny<string>(), It.IsAny<ICommunication>())).Returns(hostObject.Object);
|
||||
|
||||
sut = new ClientHost("net:pipe://some/address", hostObjectFactory.Object, logger.Object, PROCESS_ID);
|
||||
sut = new ClientHost("net:pipe://some/address", hostObjectFactory.Object, logger.Object, PROCESS_ID, 0);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
|
|
@ -72,7 +72,7 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
|
|||
clientHost.VerifyNoOtherCalls();
|
||||
|
||||
Assert.IsFalse(stopWatch.IsRunning);
|
||||
Assert.IsTrue(stopWatch.ElapsedMilliseconds > timeout_ms);
|
||||
Assert.IsTrue(stopWatch.ElapsedMilliseconds >= timeout_ms);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
|
|
@ -28,7 +28,12 @@ namespace SafeExamBrowser.Client.Communication
|
|||
public event CommunicationEventHandler RuntimeDisconnected;
|
||||
public event CommunicationEventHandler Shutdown;
|
||||
|
||||
public ClientHost(string address, IHostObjectFactory factory, ILogger logger, int processId) : base(address, factory, logger)
|
||||
public ClientHost(
|
||||
string address,
|
||||
IHostObjectFactory factory,
|
||||
ILogger logger,
|
||||
int processId,
|
||||
int timeout_ms) : base(address, factory, logger, timeout_ms)
|
||||
{
|
||||
this.processId = processId;
|
||||
}
|
||||
|
|
|
@ -180,9 +180,10 @@ namespace SafeExamBrowser.Client
|
|||
|
||||
private IOperation BuildClientHostOperation()
|
||||
{
|
||||
const int FIVE_SECONDS = 5000;
|
||||
var processId = Process.GetCurrentProcess().Id;
|
||||
var factory = new HostObjectFactory();
|
||||
var host = new ClientHost(configuration.AppConfig.ClientAddress, factory, new ModuleLogger(logger, nameof(ClientHost)), processId);
|
||||
var host = new ClientHost(configuration.AppConfig.ClientAddress, factory, new ModuleLogger(logger, nameof(ClientHost)), processId, FIVE_SECONDS);
|
||||
var operation = new CommunicationHostOperation(host, logger);
|
||||
|
||||
clientHost = host;
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace SafeExamBrowser.Communication.UnitTests.Hosts
|
|||
public Func<Message, Response> OnReceiveStub { get; set; }
|
||||
public Func<SimpleMessagePurport, Response> OnReceiveSimpleMessageStub { get; set; }
|
||||
|
||||
public BaseHostStub(string address, IHostObjectFactory factory, ILogger logger) : base(address, factory, logger)
|
||||
public BaseHostStub(string address, IHostObjectFactory factory, ILogger logger, int timeout_ms) : base(address, factory, logger, timeout_ms)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace SafeExamBrowser.Communication.UnitTests.Hosts
|
|||
|
||||
hostObjectFactory.Setup(f => f.CreateObject(It.IsAny<string>(), It.IsAny<ICommunication>())).Returns(hostObject.Object);
|
||||
|
||||
sut = new BaseHostStub("net.pipe://some/address/here", hostObjectFactory.Object, logger.Object);
|
||||
sut = new BaseHostStub("net.pipe://some/address/here", hostObjectFactory.Object, logger.Object, 10);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
@ -56,7 +56,6 @@ namespace SafeExamBrowser.Communication.UnitTests.Hosts
|
|||
[ExpectedException(typeof(CommunicationException))]
|
||||
public void MustCorrectlyHandleStartupException()
|
||||
{
|
||||
// TODO: Takes waaay too long, extract timeout (move to constructor like in ClientOperation)!
|
||||
hostObject.Setup(h => h.Open()).Throws<Exception>();
|
||||
|
||||
sut.Start();
|
||||
|
|
|
@ -22,13 +22,13 @@ namespace SafeExamBrowser.Communication.Hosts
|
|||
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
|
||||
public abstract class BaseHost : ICommunication, ICommunicationHost
|
||||
{
|
||||
private const int FIVE_SECONDS = 5000;
|
||||
private readonly object @lock = new object();
|
||||
|
||||
private string address;
|
||||
private IHostObject host;
|
||||
private IHostObjectFactory factory;
|
||||
private Thread hostThread;
|
||||
private int timeout_ms;
|
||||
|
||||
protected Guid? CommunicationToken { get; private set; }
|
||||
protected ILogger Logger { get; private set; }
|
||||
|
@ -44,11 +44,12 @@ namespace SafeExamBrowser.Communication.Hosts
|
|||
}
|
||||
}
|
||||
|
||||
public BaseHost(string address, IHostObjectFactory factory, ILogger logger)
|
||||
public BaseHost(string address, IHostObjectFactory factory, ILogger logger, int timeout_ms)
|
||||
{
|
||||
this.address = address;
|
||||
this.factory = factory;
|
||||
this.Logger = logger;
|
||||
this.timeout_ms = timeout_ms;
|
||||
}
|
||||
|
||||
protected abstract bool OnConnect(Guid? token);
|
||||
|
@ -137,11 +138,11 @@ namespace SafeExamBrowser.Communication.Hosts
|
|||
hostThread.IsBackground = true;
|
||||
hostThread.Start();
|
||||
|
||||
var success = startedEvent.WaitOne(FIVE_SECONDS);
|
||||
var success = startedEvent.WaitOne(timeout_ms);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
throw new CommunicationException($"Failed to start communication host for endpoint '{address}' within {FIVE_SECONDS / 1000} seconds!", exception);
|
||||
throw new CommunicationException($"Failed to start communication host for endpoint '{address}' within {timeout_ms / 1000} seconds!", exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -202,7 +203,7 @@ namespace SafeExamBrowser.Communication.Hosts
|
|||
try
|
||||
{
|
||||
host?.Close();
|
||||
success = hostThread?.Join(FIVE_SECONDS) == true;
|
||||
success = hostThread?.Join(timeout_ms) == true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Communication
|
|||
|
||||
hostObjectFactory.Setup(f => f.CreateObject(It.IsAny<string>(), It.IsAny<ICommunication>())).Returns(hostObject.Object);
|
||||
|
||||
sut = new RuntimeHost("net:pipe://some/address", configuration.Object, hostObjectFactory.Object, logger.Object);
|
||||
sut = new RuntimeHost("net:pipe://some/address", configuration.Object, hostObjectFactory.Object, logger.Object, 0);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
|
|
@ -7,12 +7,12 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using SafeExamBrowser.Communication.Hosts;
|
||||
using SafeExamBrowser.Contracts.Communication.Data;
|
||||
using SafeExamBrowser.Contracts.Communication.Events;
|
||||
using SafeExamBrowser.Contracts.Communication.Hosts;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Communication.Hosts;
|
||||
|
||||
namespace SafeExamBrowser.Runtime.Communication
|
||||
{
|
||||
|
@ -29,7 +29,12 @@ namespace SafeExamBrowser.Runtime.Communication
|
|||
public event CommunicationEventHandler<ReconfigurationEventArgs> ReconfigurationRequested;
|
||||
public event CommunicationEventHandler ShutdownRequested;
|
||||
|
||||
public RuntimeHost(string address, IConfigurationRepository configuration, IHostObjectFactory factory, ILogger logger) : base(address, factory, logger)
|
||||
public RuntimeHost(
|
||||
string address,
|
||||
IConfigurationRepository configuration,
|
||||
IHostObjectFactory factory,
|
||||
ILogger logger,
|
||||
int timeout_ms) : base(address, factory, logger, timeout_ms)
|
||||
{
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,8 @@ namespace SafeExamBrowser.Runtime
|
|||
|
||||
internal void BuildObjectGraph(Action shutdown)
|
||||
{
|
||||
const int STARTUP_TIMEOUT_MS = 15000;
|
||||
const int FIVE_SECONDS = 5000;
|
||||
const int FIFTEEN_SECONDS = 15000;
|
||||
|
||||
var args = Environment.GetCommandLineArgs();
|
||||
var configuration = BuildConfigurationRepository();
|
||||
|
@ -60,7 +61,7 @@ namespace SafeExamBrowser.Runtime
|
|||
var processFactory = new ProcessFactory(new ModuleLogger(logger, nameof(ProcessFactory)));
|
||||
var proxyFactory = new ProxyFactory(new ProxyObjectFactory(), logger);
|
||||
var resourceLoader = new ResourceLoader();
|
||||
var runtimeHost = new RuntimeHost(appConfig.RuntimeAddress, configuration, new HostObjectFactory(), new ModuleLogger(logger, nameof(RuntimeHost)));
|
||||
var runtimeHost = new RuntimeHost(appConfig.RuntimeAddress, configuration, new HostObjectFactory(), new ModuleLogger(logger, nameof(RuntimeHost)), FIVE_SECONDS);
|
||||
var serviceProxy = new ServiceProxy(appConfig.ServiceAddress, new ProxyObjectFactory(), new ModuleLogger(logger, nameof(ServiceProxy)));
|
||||
var uiFactory = new UserInterfaceFactory(text);
|
||||
|
||||
|
@ -73,9 +74,9 @@ namespace SafeExamBrowser.Runtime
|
|||
sessionOperations.Enqueue(new ConfigurationOperation(appConfig, configuration, logger, messageBox, resourceLoader, runtimeHost, text, uiFactory, args));
|
||||
sessionOperations.Enqueue(new SessionInitializationOperation(configuration, logger, runtimeHost));
|
||||
sessionOperations.Enqueue(new ServiceOperation(configuration, logger, serviceProxy, text));
|
||||
sessionOperations.Enqueue(new ClientTerminationOperation(configuration, logger, processFactory, proxyFactory, runtimeHost, STARTUP_TIMEOUT_MS));
|
||||
sessionOperations.Enqueue(new ClientTerminationOperation(configuration, logger, processFactory, proxyFactory, runtimeHost, FIFTEEN_SECONDS));
|
||||
sessionOperations.Enqueue(new KioskModeOperation(configuration, desktopFactory, explorerShell, logger, processFactory));
|
||||
sessionOperations.Enqueue(new ClientOperation(configuration, logger, processFactory, proxyFactory, runtimeHost, STARTUP_TIMEOUT_MS));
|
||||
sessionOperations.Enqueue(new ClientOperation(configuration, logger, processFactory, proxyFactory, runtimeHost, FIFTEEN_SECONDS));
|
||||
|
||||
var bootstrapSequence = new OperationSequence(logger, bootstrapOperations);
|
||||
var sessionSequence = new OperationSequence(logger, sessionOperations);
|
||||
|
|
Loading…
Reference in a new issue