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) 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 try
{ {
@ -140,7 +140,7 @@ namespace GameServiceWarden.Core.Games
} }
catch (AggregateException e) 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(); stopToken.Dispose();
} }

View File

@ -3,6 +3,7 @@ using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.IO.Pipes; using System.IO.Pipes;
using System.Net.Sockets;
using System.Text.Json; using System.Text.Json;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -22,8 +23,10 @@ namespace GameServiceWarden.Core.UI
public BlockingCollection<(string, CommunicableType, byte[])> RequestQueue { get; private set; } public BlockingCollection<(string, CommunicableType, byte[])> RequestQueue { get; private set; }
private volatile bool active; private volatile bool active;
public bool IsRunning { get => active; } public bool IsRunning { get => active; }
private Task acceptTask; private Task connectionTask;
private CancellationTokenSource stopAcceptingToken; private CancellationTokenSource stopAcceptingToken;
private volatile NamedPipeServerStream connectingPipe;
public IPCMediator(string name) public IPCMediator(string name)
{ {
this.name = name; this.name = name;
@ -37,7 +40,7 @@ namespace GameServiceWarden.Core.UI
Logger.Log($"IPCMediator with name \"{name}\" opened."); Logger.Log($"IPCMediator with name \"{name}\" opened.");
active = true; active = true;
stopAcceptingToken = new CancellationTokenSource(); stopAcceptingToken = new CancellationTokenSource();
acceptTask = AcceptConnections(); connectionTask = AcceptConnections();
Logger.Log($"IPCMediator \"{name}\" has begun asynchronously accepting interfaces.", LogLevel.DEBUG); Logger.Log($"IPCMediator \"{name}\" has begun asynchronously accepting interfaces.", LogLevel.DEBUG);
} }
@ -47,15 +50,16 @@ namespace GameServiceWarden.Core.UI
Logger.Log("Closing IPC mediator."); Logger.Log("Closing IPC mediator.");
active = false; active = false;
stopAcceptingToken.Cancel(); stopAcceptingToken.Cancel();
connectingPipe.Dispose();
InitiateDisconnectAll("Closing GameServiceWarden.").Wait();
try 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) 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(); RequestQueue.CompleteAdding();
stopAcceptingToken.Dispose(); stopAcceptingToken.Dispose();
} }
@ -110,10 +114,10 @@ namespace GameServiceWarden.Core.UI
Logger.Log("Accepting Interface connections."); Logger.Log("Accepting Interface connections.");
while (active) 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); Logger.Log("Waiting for connection.", LogLevel.DEBUG);
await pipe.WaitForConnectionAsync(stopAcceptingToken.Token); await connectingPipe.WaitForConnectionAsync(stopAcceptingToken.Token);
connectionTasks.Add(OnConnection(pipe)); connectionTasks.Add(OnConnection(connectingPipe));
for (int i = 0; i < connectionTasks.Count; i++) for (int i = 0; i < connectionTasks.Count; i++)
{ {
if (connectionTasks[i].IsCompleted) { if (connectionTasks[i].IsCompleted) {

View File

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