mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 22:56:29 +00:00
Errors sending to UI
notifying client of AI model conversion
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="LazyCache.AspNetCore" Version="2.4.0" />
|
||||
<PackageReference Include="MediatR" Version="12.4.1" />
|
||||
<PackageReference Include="MessagePack" Version="3.1.0" />
|
||||
<PackageReference Include="MessagePack.Annotations" Version="3.1.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.0" />
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace Azaion.CommonSecurity.DTO.Commands;
|
||||
|
||||
[MessagePackObject]
|
||||
public class RemoteCommand(CommandType commandType, byte[]? data = null)
|
||||
public class RemoteCommand(CommandType commandType, byte[]? data = null, string? message = null)
|
||||
{
|
||||
[Key("CommandType")]
|
||||
public CommandType CommandType { get; set; } = commandType;
|
||||
@@ -11,11 +11,14 @@ public class RemoteCommand(CommandType commandType, byte[]? data = null)
|
||||
[Key("Data")]
|
||||
public byte[]? Data { get; set; } = data;
|
||||
|
||||
[Key("Message")]
|
||||
public string? Message { get; set; } = message;
|
||||
|
||||
public static RemoteCommand Create(CommandType commandType) =>
|
||||
new(commandType);
|
||||
|
||||
public static RemoteCommand Create<T>(CommandType commandType, T data) where T : class =>
|
||||
new(commandType, MessagePackSerializer.Serialize(data));
|
||||
public static RemoteCommand Create<T>(CommandType commandType, T data, string? message = null) where T : class =>
|
||||
new(commandType, MessagePackSerializer.Serialize(data), message);
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
@@ -34,7 +37,12 @@ public enum CommandType
|
||||
None = 0,
|
||||
Login = 10,
|
||||
Load = 20,
|
||||
DataBytes = 25,
|
||||
Inference = 30,
|
||||
InferenceData = 35,
|
||||
StopInference = 40,
|
||||
Exit = 100
|
||||
AIAvailabilityCheck = 80,
|
||||
AIAvailabilityResult = 85,
|
||||
Error = 90,
|
||||
Exit = 100,
|
||||
}
|
||||
@@ -10,7 +10,7 @@ public abstract class ExternalClientConfig
|
||||
|
||||
public class InferenceClientConfig : ExternalClientConfig
|
||||
{
|
||||
public string ApiUrl { get; set; }
|
||||
public string ApiUrl { get; set; } = null!;
|
||||
}
|
||||
|
||||
public class GpsDeniedClientConfig : ExternalClientConfig
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Azaion.Common.Extensions;
|
||||
namespace Azaion.CommonSecurity.DTO;
|
||||
|
||||
public static class EnumerableExtensions
|
||||
{
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using Azaion.Common.Extensions;
|
||||
|
||||
namespace Azaion.CommonSecurity.DTO;
|
||||
namespace Azaion.CommonSecurity.DTO;
|
||||
|
||||
public enum RoleEnum
|
||||
{
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace Azaion.CommonSecurity.Exceptions;
|
||||
|
||||
public class BusinessException(string message) : Exception(message);
|
||||
@@ -1,104 +0,0 @@
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using Azaion.CommonSecurity.DTO;
|
||||
using Azaion.CommonSecurity.DTO.Commands;
|
||||
using MessagePack;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NetMQ;
|
||||
using NetMQ.Sockets;
|
||||
|
||||
namespace Azaion.CommonSecurity.Services;
|
||||
|
||||
public interface IInferenceClient
|
||||
{
|
||||
void Send(RemoteCommand create);
|
||||
T? Get<T>(int retries = 24, int tryTimeoutSeconds = 5, CancellationToken ct = default) where T : class;
|
||||
byte[]? GetBytes(int retries = 24, int tryTimeoutSeconds = 5, CancellationToken ct = default);
|
||||
void Stop();
|
||||
}
|
||||
|
||||
public class InferenceClient : IInferenceClient
|
||||
{
|
||||
private readonly DealerSocket _dealer = new();
|
||||
private readonly Guid _clientId = Guid.NewGuid();
|
||||
private readonly InferenceClientConfig _inferenceClientConfig;
|
||||
|
||||
public InferenceClient(IOptions<InferenceClientConfig> config)
|
||||
{
|
||||
_inferenceClientConfig = config.Value;
|
||||
Start();
|
||||
_ = Task.Run(ProcessClientCommands);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
try
|
||||
{
|
||||
using var process = new Process();
|
||||
process.StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = SecurityConstants.EXTERNAL_INFERENCE_PATH,
|
||||
Arguments = $"--port {_inferenceClientConfig.ZeroMqPort} --api {_inferenceClientConfig.ApiUrl}",
|
||||
//RedirectStandardOutput = true,
|
||||
//RedirectStandardError = true,
|
||||
//CreateNoWindow = true
|
||||
};
|
||||
|
||||
process.OutputDataReceived += (_, e) => { if (e.Data != null) Console.WriteLine(e.Data); };
|
||||
process.ErrorDataReceived += (_, e) => { if (e.Data != null) Console.WriteLine(e.Data); };
|
||||
process.Start();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
//throw;
|
||||
}
|
||||
|
||||
_dealer.Options.Identity = Encoding.UTF8.GetBytes(_clientId.ToString("N"));
|
||||
_dealer.Connect($"tcp://{_inferenceClientConfig.ZeroMqHost}:{_inferenceClientConfig.ZeroMqPort}");
|
||||
}
|
||||
private async Task ProcessClientCommands()
|
||||
{
|
||||
//TODO: implement always on ready to client's requests. Utilize RemoteCommand
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
if (!_dealer.IsDisposed)
|
||||
{
|
||||
_dealer.SendFrame(MessagePackSerializer.Serialize(new RemoteCommand(CommandType.Exit)));
|
||||
_dealer.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public void Send(RemoteCommand command)
|
||||
{
|
||||
_dealer.SendFrame(MessagePackSerializer.Serialize(command));
|
||||
}
|
||||
|
||||
public T? Get<T>(int retries = 24, int tryTimeoutSeconds = 5, CancellationToken ct = default) where T : class
|
||||
{
|
||||
var bytes = GetBytes(retries, tryTimeoutSeconds, ct);
|
||||
return bytes != null ? MessagePackSerializer.Deserialize<T>(bytes, cancellationToken: ct) : null;
|
||||
}
|
||||
|
||||
public byte[]? GetBytes(int retries = 24, int tryTimeoutSeconds = 5, CancellationToken ct = default)
|
||||
{
|
||||
var tryNum = 0;
|
||||
while (!ct.IsCancellationRequested && tryNum < retries)
|
||||
{
|
||||
tryNum++;
|
||||
if (!_dealer.TryReceiveFrameBytes(TimeSpan.FromSeconds(tryTimeoutSeconds), out var bytes))
|
||||
continue;
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
if (!ct.IsCancellationRequested)
|
||||
throw new Exception($"Unable to get bytes after {tryNum - 1} retries, {tryTimeoutSeconds} seconds each");
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,8 @@
|
||||
using Azaion.CommonSecurity.DTO.Commands;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Azaion.CommonSecurity.Services;
|
||||
|
||||
public interface IResourceLoader
|
||||
{
|
||||
MemoryStream LoadFile(string fileName, string? folder = null);
|
||||
}
|
||||
|
||||
public class ResourceLoader([FromKeyedServices(SecurityConstants.EXTERNAL_INFERENCE_PATH)] IInferenceClient inferenceClient) : IResourceLoader
|
||||
{
|
||||
public MemoryStream LoadFile(string fileName, string? folder = null)
|
||||
{
|
||||
inferenceClient.Send(RemoteCommand.Create(CommandType.Load, new LoadFileData(fileName, folder)));
|
||||
var bytes = inferenceClient.GetBytes(2, 3);
|
||||
if (bytes == null)
|
||||
throw new Exception($"Unable to receive {fileName}");
|
||||
|
||||
return new MemoryStream(bytes);
|
||||
}
|
||||
MemoryStream LoadFile(string fileName, string? folder, TimeSpan? timeout = null);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user