Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/ByteSync.Client/Assets/Resources/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/ByteSync.Client/Assets/Resources/Resources.fr.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1541,4 +1541,10 @@ Voulez-vous enregistrer ce nouveau Profil de Session avec ce nom ?</value>
<data name="JoinCloudSession_TimeoutError" xml:space="preserve">
<value>Le délai d'attente a expiré.</value>
</data>
<data name="JoinCloudSession_CanceledByUser" xml:space="preserve">
<value>Opération annulée par l'utilisateur.</value>
</data>
<data name="CreateCloudSession_CanceledByUser" xml:space="preserve">
<value>Opération annulée par l'utilisateur.</value>
</data>
</root>
6 changes: 6 additions & 0 deletions src/ByteSync.Client/Assets/Resources/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1679,4 +1679,10 @@ Do you want to save this new Session Profile with this name?</value>
<data name="JoinCloudSession_TimeoutError" xml:space="preserve">
<value>The waiting period has expired.</value>
</data>
<data name="JoinCloudSession_CanceledByUser" xml:space="preserve">
<value>Operation canceled by the user.</value>
</data>
<data name="CreateCloudSession_CanceledByUser" xml:space="preserve">
<value>Operation canceled by the user.</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ public enum CreateSessionStatus
{
Success = 1,
Error = 2,
CanceledByUser = 3,
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ public interface ICloudSessionConnectionService
Task OnJoinSessionError(JoinSessionError joinSessionError);

Task OnCreateSessionError(CreateSessionError createSessionError);

Task HandleJoinSessionError(Exception exception);
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,29 @@ public async Task OnCreateSessionError(CreateSessionError createSessionError)

await InitializeConnection(SessionConnectionStatus.NoSession);
}

public async Task HandleJoinSessionError(Exception exception)
{
_logger.LogError(exception, "An error occurred while joining the Cloud Session");

var status = JoinSessionStatus.UnexpectedError;

if ((exception is TaskCanceledException || exception.InnerException is TaskCanceledException)
&& _cloudSessionConnectionRepository.CancellationToken.IsCancellationRequested)
{
status = JoinSessionStatus.CanceledByUser;
}
else if (exception is TimeoutException)
{
status = JoinSessionStatus.TimeoutError;
}

var joinSessionError = new JoinSessionError
{
Exception = exception,
Status = status
};

await OnJoinSessionError(joinSessionError);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,21 @@ public CreateSessionService(ICloudSessionConnectionRepository cloudSessionConnec
}
catch (Exception ex)
{
var status = CreateSessionStatus.Error;
if (ex is TaskCanceledException || ex.InnerException is TaskCanceledException)
{
status = CreateSessionStatus.CanceledByUser;
}

var createSessionError = new CreateSessionError
{
Exception = ex,
Status = CreateSessionStatus.Error
Status = status
};

await _cloudSessionConnectionService.OnCreateSessionError(createSessionError);

throw;
return null;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,21 +90,7 @@ await _cloudSessionConnectionRepository.WaitOrThrowAsync(request.SessionId,
}
catch (Exception ex)
{
_logger.LogError(ex, "OnCloudSessionPasswordExchangeKeyGiven");

var status = JoinSessionStatus.UnexpectedError;
if (ex is TimeoutException)
{
status = JoinSessionStatus.TimeoutError;
}

var joinSessionError = new JoinSessionError
{
Exception = ex,
Status = status
};

await _cloudSessionConnectionService.OnJoinSessionError(joinSessionError);
await _cloudSessionConnectionService.HandleJoinSessionError(ex);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,7 @@ public async Task JoinSession(string sessionId, string sessionPassword, RunCloud
}
catch (Exception ex)
{
var status = JoinSessionStatus.UnexpectedError;
if (ex is TimeoutException)
{
status = JoinSessionStatus.TimeoutError;
}


var joinSessionError = new JoinSessionError
{
Exception = ex,
Status = status
};

await _cloudSessionConnectionService.OnJoinSessionError(joinSessionError);

throw;
await _cloudSessionConnectionService.HandleJoinSessionError(ex);
}
}

Expand Down Expand Up @@ -122,7 +107,8 @@ private async Task DoStartJoinSession(string sessionId, string sessionPassword,
else
{
await _cloudSessionConnectionRepository.WaitOrThrowAsync(sessionId,
data => data.WaitForPasswordExchangeKeyEvent, data => data.WaitTimeSpan, "Keys exchange failed: no key received");
data => data.WaitForPasswordExchangeKeyEvent, data => data.WaitTimeSpan, "Keys exchange failed: no key received",
_cloudSessionConnectionRepository.CancellationToken);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ public async Task Process(CloudSessionResult cloudSessionResult, ValidateJoinClo
var encryptedSessionMemberPrivateData = _dataEncrypter.EncryptSessionMemberPrivateData(sessionMemberPrivateData);
var finalizeParameters = new FinalizeJoinCloudSessionParameters(parameters, encryptedSessionMemberPrivateData);

var finalizeJoinSessionResult = await _cloudSessionApiClient.FinalizeJoinCloudSession(finalizeParameters);
var finalizeJoinSessionResult = await _cloudSessionApiClient.FinalizeJoinCloudSession(finalizeParameters,
_cloudSessionConnectionRepository.CancellationToken);

if (finalizeJoinSessionResult.Status == FinalizeJoinSessionStatuses.AuthIsNotChecked)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ private void OnCreateSessionError(CreateSessionError? createSessionError)
case CreateSessionStatus.Error:
UpdateErrorMessage(nameof(Resources.CreateCloudSession_UnknownError), createSessionError.Exception);
break;

case CreateSessionStatus.CanceledByUser:
UpdateErrorMessage(nameof(Resources.CreateCloudSession_CanceledByUser));
break;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,10 @@ private void OnCloudSessionJoinError(JoinSessionError? joinSessionError)
case JoinSessionStatus.TimeoutError:
UpdateErrorMessage(nameof(Resources.JoinCloudSession_TimeoutError), joinSessionError.Exception);
break;

case JoinSessionStatus.CanceledByUser:
UpdateErrorMessage(nameof(Resources.JoinCloudSession_CanceledByUser));
break;

default:
UpdateErrorMessage(nameof(Resources.JoinCloudSession_UnkownError), joinSessionError.Exception);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ public enum JoinSessionStatus
WrongPassword = 9,
UnexpectedError = 10,
TimeoutError = 11,
Unknown_12 = 12,
CanceledByUser = 12,
}
21 changes: 14 additions & 7 deletions src/ByteSync.Common/Controls/BaseRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
using System.Threading;
using System.Threading.Tasks;
using ByteSync.Common.Helpers;
using ByteSync.Common.Interfaces;
using Serilog;

// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable MemberCanBeProtected.Global
namespace ByteSync.Common.Controls;

public abstract class BaseRepository<T>
public abstract class BaseRepository<T> : IRepository<T>
{
protected BaseRepository()
{
Expand Down Expand Up @@ -136,16 +137,18 @@ public T2 Get<T2>(string? dataId, Func<T, T2> func)
return CheckAndRun(dataId, func);
}

public async Task WaitOrThrowAsync(string dataId, Func<T, EventWaitHandle> func, TimeSpan? timeout, string exceptionMessage)
public async Task WaitOrThrowAsync(string dataId, Func<T, EventWaitHandle> func, TimeSpan? timeout, string exceptionMessage,
CancellationToken cancellationToken = default)
{
await WaitOrThrowAsync(dataId, func, _ => timeout, exceptionMessage);
await WaitOrThrowAsync(dataId, func, _ => timeout, exceptionMessage, cancellationToken);
}

public async Task WaitOrThrowAsync(string dataId, Func<T, EventWaitHandle> func, Func<T, TimeSpan?> getTimeSpan, string exceptionMessage)
public async Task WaitOrThrowAsync(string dataId, Func<T, EventWaitHandle> func, Func<T, TimeSpan?> getTimeSpan, string exceptionMessage,
CancellationToken cancellationToken = default)
{
await Task.Run(() =>
{
bool isWaitOK = Wait(dataId, func, getTimeSpan);
bool isWaitOK = Wait(dataId, func, getTimeSpan, cancellationToken);

if (!isWaitOK)
{
Expand All @@ -167,7 +170,7 @@ public async Task<bool> WaitAsync(string dataId, Func<T, EventWaitHandle> func,
});
}

public bool Wait(string dataId, Func<T, EventWaitHandle> func, Func<T, TimeSpan?> getTimeSpan)
public bool Wait(string dataId, Func<T, EventWaitHandle> func, Func<T, TimeSpan?> getTimeSpan, CancellationToken cancellationToken = default)
{
EventWaitHandle? waitHandle = null;
TimeSpan? timeout = null;
Expand All @@ -182,13 +185,17 @@ public bool Wait(string dataId, Func<T, EventWaitHandle> func, Func<T, TimeSpan?

CheckAndRun(dataId, myFunc);

// Le code ci-dessous doit être exécuté en dehors du "lock"
timeout ??= new TimeSpan(-1);
List<WaitHandle> waitHandles = new List<WaitHandle> {waitHandle!};
if (endEvent != null)
{
waitHandles.Add(endEvent);
}
if (cancellationToken.CanBeCanceled)
{
waitHandles.Add(cancellationToken.WaitHandle);
}

int index = WaitHandle.WaitAny(waitHandles.ToArray(), timeout.Value);

if (index == 0)
Expand Down
8 changes: 5 additions & 3 deletions src/ByteSync.Common/Interfaces/IRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ public interface IRepository<T>

T2 Get<T2>(string lobbyId, Func<T, T2> func);

public Task WaitOrThrowAsync(string dataId, Func<T, EventWaitHandle> func, TimeSpan? timeout, string exceptionMessage);
public Task WaitOrThrowAsync(string dataId, Func<T, EventWaitHandle> func, TimeSpan? timeout, string exceptionMessage,
CancellationToken cancellationToken = default);

public Task WaitOrThrowAsync(string dataId, Func<T, EventWaitHandle> func, Func<T, TimeSpan?> getTimeSpan, string exceptionMessage);
public Task WaitOrThrowAsync(string dataId, Func<T, EventWaitHandle> func, Func<T, TimeSpan?> getTimeSpan, string exceptionMessage,
CancellationToken cancellationToken = default);

public Task<bool> WaitAsync(string dataId, Func<T, EventWaitHandle> func, TimeSpan? timeout);

public Task<bool> WaitAsync(string dataId, Func<T, EventWaitHandle> func, Func<T, TimeSpan?> getTimeSpan);

public bool Wait(string dataId, Func<T, EventWaitHandle> func, Func<T, TimeSpan?> getTimeSpan);
public bool Wait(string dataId, Func<T, EventWaitHandle> func, Func<T, TimeSpan?> getTimeSpan, CancellationToken cancellationToken = default);
}
Original file line number Diff line number Diff line change
Expand Up @@ -234,15 +234,13 @@ public async Task CreateCloudSession_ShouldThrowTaskCanceledException_WhenCancel
.ReturnsAsync(dummyResult);

// Act
Func<Task> act = async () => await _service.CreateCloudSession(request);
await _service.CreateCloudSession(request);

// Assert
await act.Should().ThrowAsync<TaskCanceledException>();

_cloudSessionConnectionServiceMock.Verify(x => x.OnCreateSessionError(
It.Is<CreateSessionError>(err =>
err.Exception is TaskCanceledException &&
err.Status == CreateSessionStatus.Error)),
err.Status == CreateSessionStatus.CanceledByUser)),
Times.Once);
}

Expand All @@ -261,11 +259,9 @@ public async Task CreateCloudSession_ShouldThrowException_WhenCloudSessionApiCli
.ThrowsAsync(exception);

// Act
Func<Task> act = async () => await _service.CreateCloudSession(request);
await _service.CreateCloudSession(request);

// Assert
await act.Should().ThrowAsync<InvalidOperationException>().WithMessage("Test exception");

_cloudSessionConnectionServiceMock.Verify(x => x.OnCreateSessionError(
It.Is<CreateSessionError>(err =>
err.Exception == exception &&
Expand Down