Files
mROA/mROA/Implementation/Frontend/RequestExtractor.cs
T

145 lines
5.2 KiB
C#

using System;
#if TRACE
using System.Diagnostics;
#endif
using System.Threading;
using System.Threading.Tasks;
using mROA.Abstract;
// ReSharper disable MethodHasAsyncOverload
namespace mROA.Implementation.Frontend
{
public class RequestExtractor : IRequestExtractor
{
private IExecuteModule? _executeModule;
private IMethodRepository? _methodRepository;
// private IContextRepository? _realContextRepository;
// private IContextRepository? _remoteContextRepository;
private IRepresentationModule? _representationModule;
private IContextualSerializationToolKit? _serializationToolkit;
private IEndPointContext _context;
public void Inject<T>(T dependency)
{
switch (dependency)
{
case IExecuteModule executeModule:
_executeModule = executeModule;
break;
case IMethodRepository methodRepository:
_methodRepository = methodRepository;
break;
case IRepresentationModule representationModule:
_representationModule = representationModule;
break;
case IContextualSerializationToolKit serializationToolkit:
_serializationToolkit = serializationToolkit;
break;
case IEndPointContext remoteContext:
_context = remoteContext;
break;
}
}
public async Task StartExtraction()
{
ThrowIfNotInjected();
try
{
#if TRACE
var sw = new Stopwatch();
#endif
var streamTokenSource = new CancellationTokenSource();
var query = _representationModule!.GetStream(m =>
m.MessageType is EMessageType.CallRequest or EMessageType.CancelRequest
or EMessageType.EventRequest or EMessageType.ClientDisconnect, _context,
streamTokenSource.Token,
m => m.MessageType == EMessageType.CallRequest ? typeof(DefaultCallRequest) : null,
m => m.MessageType == EMessageType.CancelRequest ? typeof(CancelRequest) : null,
m => m.MessageType == EMessageType.EventRequest ? typeof(DefaultCallRequest) : null,
m => m.MessageType == EMessageType.ClientDisconnect ? typeof(ClientDisconnect) : null);
await foreach (var command in query)
{
#if TRACE
Console.WriteLine("Waiting for request...");
if (sw.IsRunning)
{
sw.Stop();
Console.WriteLine(
$"Request handling took {Math.Round(sw.Elapsed.TotalMilliseconds * 1000.0)} microseconds.");
}
#endif
#if TRACE
Console.WriteLine("Request received");
sw.Restart();
#endif
switch (command.originalType)
{
case EMessageType.CallRequest:
HandleCallRequest((command.parced as DefaultCallRequest)!);
break;
case EMessageType.ClientDisconnect:
return;
case EMessageType.EventRequest:
HandleEventRequest((command.parced as DefaultCallRequest)!);
break;
case EMessageType.CancelRequest:
HandleCancelRequest((command.parced as CancelRequest)!);
break;
default:
continue;
}
}
}
catch
{
}
}
private void ThrowIfNotInjected()
{
if (_serializationToolkit == null)
throw new NullReferenceException("Serializing toolkit is null.");
if (_executeModule == null)
throw new NullReferenceException("Execute module is null.");
if (_representationModule == null)
throw new NullReferenceException("Representation module is null.");
if (_methodRepository == null)
throw new NullReferenceException("Method repository is null.");
}
private void HandleCancelRequest(CancelRequest req)
{
_executeModule!.Execute(req, _context.RealRepository, _representationModule!, _context);
}
private void HandleCallRequest(DefaultCallRequest request)
{
var result = _executeModule!.Execute(request, _context.RealRepository, _representationModule!, _context);
var resultType = result.MessageType;
if (resultType == EMessageType.Unknown)
{
return;
}
_representationModule!.PostCallMessage(request.Id, resultType, result, _context);
}
private void HandleEventRequest(DefaultCallRequest request)
{
_executeModule!.Execute(request, _context.RemoteRepository, _representationModule!, _context);
}
}
}