IPCMediator now disposes of all connection pipes before waiting.

Changed mediator names in IPCMediatorTest.

Increased catching specificity from same type of exception.
This commit is contained in:
Harrison Deng 2021-04-15 22:08:25 -05:00
parent a0775fdf8e
commit 0991dc6214
3 changed files with 17 additions and 13 deletions

View File

@ -130,7 +130,7 @@ namespace GameServiceWarden.Core.Games
}
catch (AggregateException e)
{
e.Handle((exception) => exception is TaskCanceledException || exception is SocketException); //Task cancel for Windows, Socket for operation cancellation.
e.Handle((exception) => exception is TaskCanceledException || (exception is SocketException && exception.Message.Equals("Operation canceled"))); //Task cancel for Windows, Socket for operation cancellation.
}
try
{
@ -140,7 +140,7 @@ namespace GameServiceWarden.Core.Games
}
catch (AggregateException e)
{
e.Handle((exception) => exception is TaskCanceledException || exception is SocketException); //Same as above.
e.Handle((exception) => exception is TaskCanceledException || (exception is SocketException && exception.Message.Equals("Operation canceled"))); //Same as above.
}
stopToken.Dispose();
}

View File

@ -3,6 +3,7 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Net.Sockets;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
@ -22,8 +23,10 @@ namespace GameServiceWarden.Core.UI
public BlockingCollection<(string, CommunicableType, byte[])> RequestQueue { get; private set; }
private volatile bool active;
public bool IsRunning { get => active; }
private Task acceptTask;
private Task connectionTask;
private CancellationTokenSource stopAcceptingToken;
private volatile NamedPipeServerStream connectingPipe;
public IPCMediator(string name)
{
this.name = name;
@ -37,7 +40,7 @@ namespace GameServiceWarden.Core.UI
Logger.Log($"IPCMediator with name \"{name}\" opened.");
active = true;
stopAcceptingToken = new CancellationTokenSource();
acceptTask = AcceptConnections();
connectionTask = AcceptConnections();
Logger.Log($"IPCMediator \"{name}\" has begun asynchronously accepting interfaces.", LogLevel.DEBUG);
}
@ -47,15 +50,16 @@ namespace GameServiceWarden.Core.UI
Logger.Log("Closing IPC mediator.");
active = false;
stopAcceptingToken.Cancel();
connectingPipe.Dispose();
InitiateDisconnectAll("Closing GameServiceWarden.").Wait();
try
{
if (!acceptTask.Wait(TIMEOUT)) throw new TimeoutException($"IPCMediator \"{name}\" was unable to stop accepting task within {TIMEOUT}ms.");
if (!connectionTask.Wait(TIMEOUT)) throw new TimeoutException($"IPCMediator \"{name}\" was unable to stop accepting task within {TIMEOUT}ms.");
}
catch (AggregateException e)
{
e.Handle((exception) => exception is TaskCanceledException);
e.Handle((exception) => exception is TaskCanceledException || (exception is SocketException && exception.Message.Equals("Operation canceled")));
}
InitiateDisconnectAll("Closing IPC system.").Wait();
RequestQueue.CompleteAdding();
stopAcceptingToken.Dispose();
}
@ -110,10 +114,10 @@ namespace GameServiceWarden.Core.UI
Logger.Log("Accepting Interface connections.");
while (active)
{
NamedPipeServerStream pipe = new NamedPipeServerStream(PipeName, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
connectingPipe = new NamedPipeServerStream(PipeName, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
Logger.Log("Waiting for connection.", LogLevel.DEBUG);
await pipe.WaitForConnectionAsync(stopAcceptingToken.Token);
connectionTasks.Add(OnConnection(pipe));
await connectingPipe.WaitForConnectionAsync(stopAcceptingToken.Token);
connectionTasks.Add(OnConnection(connectingPipe));
for (int i = 0; i < connectionTasks.Count; i++)
{
if (connectionTasks[i].IsCompleted) {

View File

@ -17,7 +17,7 @@ namespace GameServiceWarden.Core.Tests.UI
public void Open_Closed_Opened()
{
//Given
const string NAME = "MEDIATOR";
const string NAME = "Open_Closed_Opened";
IPCMediator mediator = new IPCMediator(NAME);
//When
mediator.Open();
@ -29,7 +29,7 @@ namespace GameServiceWarden.Core.Tests.UI
public void Open_AlreadyOpened_Exception()
{
//Given
const string NAME = "MEDIATOR";
const string NAME = "Open_AlreadyOpened_Exception";
IPCMediator mediator = new IPCMediator(NAME);
//When
mediator.Open();
@ -41,7 +41,7 @@ namespace GameServiceWarden.Core.Tests.UI
public void Close_Opened_Closed()
{
//Given
const string NAME = "MEDIATOR";
const string NAME = "Close_Opened_Closed";
IPCMediator mediator = new IPCMediator(NAME);
//When
mediator.Open();