Добавление IDisposable

This commit is contained in:
2025-02-23 10:18:38 +03:00
parent b6226b68c9
commit ae4979c9f9
12 changed files with 207 additions and 72 deletions
@@ -21,6 +21,8 @@ namespace mROA.Implementation.Backend
public ICommandExecution Execute(ICallRequest command, IContextRepository contextRepository,
IRepresentationModule representationModule)
{
Console.WriteLine(command.GetType().Name);
if (_cancellationRepo is null)
throw new NullReferenceException("Method repository was not defined");
@@ -30,6 +32,19 @@ namespace mROA.Implementation.Backend
if (contextRepository is null)
throw new NullReferenceException("Context repository was not defined");
if (command is CancelRequest)
{
Console.WriteLine("Final cancelling request");
var cts = _cancellationRepo.GetCancellation(command.Id);
cts.Cancel();
_cancellationRepo.FreeCancelation(command.Id);
return new FinalCommandExecution
{
Id = command.Id,
CommandId = command.CommandId
};
}
var currentCommand = _methodRepo.GetMethod(command.CommandId);
if (currentCommand == null)
throw new Exception($"Command {command.CommandId} not found");
@@ -48,7 +63,14 @@ namespace mROA.Implementation.Backend
return ExecuteAsync(currentCommand, context, parameter, command, _cancellationRepo,
representationModule);
return Execute(currentCommand, context, parameter, command);
var result = Execute(currentCommand, context, parameter, command);
if (command.CommandId == -1)
{
contextRepository.ClearObject(command.ObjectId);
}
return result;
}
private static ICommandExecution Execute(MethodInfo currentCommand, object context, object? parameter,
@@ -57,9 +79,10 @@ namespace mROA.Implementation.Backend
try
{
var finalResult = currentCommand.Invoke(context, parameter is null
? new object[0]
? Array.Empty<object>()
: new[]
{ parameter });
return new TypedFinalCommandExecution
{
CommandId = command.CommandId, Result = finalResult,
@@ -77,13 +100,14 @@ namespace mROA.Implementation.Backend
}
}
private static ICommandExecution ExecuteAsync(MethodInfo currentCommand, object context, object? parameter,
private ICommandExecution ExecuteAsync(MethodInfo currentCommand, object context, object? parameter,
ICallRequest command, ICancellationRepository cancellationRepository,
IRepresentationModule representationModule)
{
var tokenSource = new CancellationTokenSource();
cancellationRepository.RegisterCancellation(command.Id, tokenSource);
var token = tokenSource.Token;
token.Register(() => Console.WriteLine($"Cancellation requested check {command.Id}"));
try
{
var result = (Task)currentCommand.Invoke(context, parameter is null
@@ -94,11 +118,16 @@ namespace mROA.Implementation.Backend
result.ContinueWith(_ =>
{
if (token.IsCancellationRequested)
return;
var payload = new FinalCommandExecution
{
Id = command.Id,
CommandId = command.CommandId
};
_cancellationRepo.FreeCancelation(command.Id);
var multiClientOwnershipRepository =
TransmissionConfig.OwnershipRepository as MultiClientOwnershipRepository;
multiClientOwnershipRepository?.RegisterOwnership(representationModule.Id);
@@ -121,7 +150,7 @@ namespace mROA.Implementation.Backend
}
}
private static ICommandExecution TypedExecuteAsync(MethodInfo currentCommand, object context, object? parameter,
private ICommandExecution TypedExecuteAsync(MethodInfo currentCommand, object context, object? parameter,
ICallRequest command, ICancellationRepository cancellationRepository,
IRepresentationModule representationModule)
{
@@ -147,6 +176,8 @@ namespace mROA.Implementation.Backend
CommandId = command.CommandId,
Type = finalResult?.GetType()
};
_cancellationRepo.FreeCancelation(command.Id);
var multiClientOwnershipRepository =
TransmissionConfig.OwnershipRepository as MultiClientOwnershipRepository;
multiClientOwnershipRepository?.RegisterOwnership(representationModule.Id);
+11 -1
View File
@@ -1,5 +1,6 @@
using System;
using System.Text.Json.Serialization;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
@@ -18,9 +19,18 @@ namespace mROA.Implementation
public Guid Id { get; set; } = Guid.NewGuid();
public int CommandId { get; set; }
public int ObjectId { get; set; } = -1;
[JsonIgnore]
public Type? ParameterType { get; set; }
public object? Parameter { get; set; }
}
public class CancelRequest : ICallRequest
{
public Guid Id { get; set; }
public int CommandId { get; set; } = -2;
public int ObjectId { get; set; } = -2;
public object? Parameter { get; set; } = null;
}
}
@@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using mROA.Abstract;
using mROA.Implementation.Backend;
@@ -53,45 +54,68 @@ namespace mROA.Implementation.Frontend
throw new NullReferenceException("Method repository is null.");
await Task.Yield();
var multiClientOwnershipRepository = TransmissionConfig.OwnershipRepository as MultiClientOwnershipRepository;
var multiClientOwnershipRepository =
TransmissionConfig.OwnershipRepository as MultiClientOwnershipRepository;
multiClientOwnershipRepository?.RegisterOwnership(_representationModule.Id);
try
{
while (true)
{
var request =
_representationModule!.GetMessage<DefaultCallRequest>(messageType: MessageType.CallRequest);
Console.WriteLine("Waiting for request...");
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
var defaultRequest =
_representationModule!.GetMessageAsync<DefaultCallRequest>(
messageType: MessageType.CallRequest, token: token);
var cancelRequest =
_representationModule!.GetMessageAsync<CancelRequest>(
messageType: MessageType.CancelRequest, token: token);
// Console.WriteLine("Executing {0}", request.Id);
if (request.Parameter is not null)
Task.WaitAny(defaultRequest, cancelRequest);
Console.WriteLine("Request received");
if (cancelRequest.IsCompleted)
{
var parameterType = _methodRepository!.GetMethod(request.CommandId).GetParameters().First()
.ParameterType;
request.Parameter = _serializationToolkit.Cast(request.Parameter, parameterType);
Console.WriteLine("Cancelling request");
var req = cancelRequest.Result;
tokenSource.Cancel();
_executeModule.Execute(req, _contextRepository, _representationModule);
}
var result = _executeModule.Execute(request, _contextRepository, _representationModule);
var resultType = MessageType.Unknown;
switch (result)
else
{
case FinalCommandExecution:
resultType = MessageType.FinishedCommandExecution;
break;
case AsyncCommandExecution:
resultType = MessageType.AsyncCommandExecution;
break;
case ExceptionCommandExecution:
resultType = MessageType.ExceptionCommandExecution;
break;
}
tokenSource.Cancel();
var request = defaultRequest.Result;
_representationModule.PostCallMessage(request.Id, resultType, result, result.GetType());
if (request.Parameter is not null)
{
var parameterType = _methodRepository!.GetMethod(request.CommandId).GetParameters().First()
.ParameterType;
request.Parameter = _serializationToolkit.Cast(request.Parameter, parameterType);
}
var result = _executeModule.Execute(request, _contextRepository, _representationModule);
var resultType = MessageType.Unknown;
switch (result)
{
case FinalCommandExecution:
resultType = MessageType.FinishedCommandExecution;
break;
case AsyncCommandExecution:
resultType = MessageType.AsyncCommandExecution;
break;
case ExceptionCommandExecution:
resultType = MessageType.ExceptionCommandExecution;
break;
}
_representationModule.PostCallMessage(request.Id, resultType, result, result.GetType());
}
}
}
catch
@@ -99,6 +123,5 @@ namespace mROA.Implementation.Frontend
multiClientOwnershipRepository?.FreeOwnership();
}
}
}
}
@@ -86,10 +86,11 @@ namespace mROA.Implementation
// Console.WriteLine("Receiving {0}", Encoding.Default.GetString(_buffer[..len]));
var message = _serialization.Deserialize<NetworkMessage>(localSpan.Span);
_messageBuffer.Add(message!);
Console.WriteLine($"Received Message {message.SchemaId} - {message.Id}");
_messageBuffer.Add(message);
_currentReceiving = Task.Run(async () => await GetNextMessage());
return message!;
return message;
}
}
}
+33 -10
View File
@@ -1,4 +1,5 @@
using System.Threading;
using System;
using System.Threading;
using System.Threading.Tasks;
using mROA.Abstract;
using mROA.Implementation.CommandExecution;
@@ -7,7 +8,7 @@ using mROA.Implementation.CommandExecution;
namespace mROA.Implementation
{
public abstract class RemoteObjectBase
public abstract class RemoteObjectBase : IDisposable
{
private readonly int _id;
private readonly IRepresentationModule _representationModule;
@@ -20,7 +21,7 @@ namespace mROA.Implementation
public int Id => _id;
public int OwnerId => _representationModule.Id;
protected async Task<T> GetResultAsync<T>(int methodId, object? parameter = default,
CancellationToken cancellationToken = default)
{
@@ -46,6 +47,7 @@ namespace mROA.Implementation
if (cancellationToken.IsCancellationRequested)
{
await _representationModule.PostCallMessageAsync(request.Id, MessageType.CancelRequest, request.Id);
localTokenSource.Cancel();
cancellationToken.ThrowIfCancellationRequested();
}
@@ -76,21 +78,42 @@ namespace mROA.Implementation
_representationModule.GetMessageAsync<ExceptionCommandExecution>(requestId: request.Id,
MessageType.ExceptionCommandExecution, localTokenSource.Token);
cancellationToken.Register(async () =>
{
Console.WriteLine("Cancelling task");
await _representationModule.PostCallMessageAsync(request.Id, MessageType.CancelRequest,
new CancelRequest
{
Id = request.Id
});
localTokenSource.Cancel();
});
Task.WaitAny(new Task[]
{
successResponse, errorResponse
errorResponse, successResponse
}, cancellationToken);
if (cancellationToken.IsCancellationRequested)
{
await _representationModule.PostCallMessageAsync(request.Id, MessageType.CancelRequest, request.Id);
cancellationToken.ThrowIfCancellationRequested();
}
Console.WriteLine($"Handling message");
// if (cancellationToken.IsCancellationRequested)
// {
// localTokenSource.Cancel();
// return;
// }
if (successResponse.IsCompletedSuccessfully)
return;
throw errorResponse.Result.GetException();
if (errorResponse.IsCompletedSuccessfully)
throw errorResponse.Result.GetException();
}
public void Dispose()
{
if (_id == -1)
return;
CallAsync(-1).Wait();
}
}
}
+5 -2
View File
@@ -57,7 +57,8 @@ namespace mROA.Implementation
{
var message = await _interaction.GetNextMessageReceiving();
if ((requestId is not null && message.Id != requestId) ||
(messageType is not null && message.SchemaId != messageType)) continue;
(messageType is not null && message.SchemaId != messageType))
continue;
_interaction.HandleMessage(message);
return message.Data;
@@ -79,7 +80,9 @@ namespace mROA.Implementation
throw new NullReferenceException("Interaction toolkit is not initialized");
if (_serialization == null)
throw new NullReferenceException("Serialization toolkit is not initialized");
Console.WriteLine($"Posting message: {id} - {messageType}");
await _interaction.PostMessage(new NetworkMessage
{ Id = id, SchemaId = messageType, Data = _serialization.Serialize(payload, payloadType) });
}