using Azaion.Common.DTO; using Azaion.Common.DTO.Config; using Azaion.Common.Extensions; using Microsoft.Extensions.Options; namespace Azaion.Common.Services.Inference; public interface IInferenceService { Task RunInference(List mediaPaths, int tileSize, CancellationToken ct = default); CancellationTokenSource InferenceCancelTokenSource { get; set; } void StopInference(); } // SHOULD BE ONLY ONE INSTANCE OF InferenceService. Do not add ANY NotificationHandler to it! // _inferenceCancelTokenSource should be created only once. public class InferenceService( IInferenceClient client, IAzaionApi azaionApi, IOptions aiConfigOptions) : IInferenceService { public CancellationTokenSource InferenceCancelTokenSource { get; set; } = new(); public CancellationTokenSource CheckAIAvailabilityTokenSource { get; set; } = new(); public async Task CheckAIAvailabilityStatus() { CheckAIAvailabilityTokenSource = new CancellationTokenSource(); while (!CheckAIAvailabilityTokenSource.IsCancellationRequested) { client.Send(RemoteCommand.Create(CommandType.AIAvailabilityCheck)); await Task.Delay(10000, CheckAIAvailabilityTokenSource.Token); } } public async Task RunInference(List mediaPaths, int tileSize, CancellationToken ct = default) { InferenceCancelTokenSource = new CancellationTokenSource(); client.Send(RemoteCommand.Create(CommandType.Login, azaionApi.Credentials)); var aiConfig = aiConfigOptions.Value; aiConfig.Paths = mediaPaths; aiConfig.TileSize = tileSize; client.Send(RemoteCommand.Create(CommandType.Inference, aiConfig)); using var combinedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(ct, InferenceCancelTokenSource.Token); await combinedTokenSource.Token.AsTask(); } public void StopInference() => client.Stop(); }