|  |  | 1 |  | using System.Text.Json; | 
|  |  | 2 |  | using LGDXRobotCloud.Data.Models.Redis; | 
|  |  | 3 |  | using LGDXRobotCloud.Protos; | 
|  |  | 4 |  | using LGDXRobotCloud.Utilities.Enums; | 
|  |  | 5 |  | using LGDXRobotCloud.Utilities.Helpers; | 
|  |  | 6 |  | using NRedisStack.RedisStackCommands; | 
|  |  | 7 |  | using NRedisStack.Search; | 
|  |  | 8 |  | using StackExchange.Redis; | 
|  |  | 9 |  | using static StackExchange.Redis.RedisChannel; | 
|  |  | 10 |  |  | 
|  |  | 11 |  | namespace LGDXRobotCloud.API.Repositories; | 
|  |  | 12 |  |  | 
|  |  | 13 |  | public interface IAutoTaskRepository | 
|  |  | 14 |  | { | 
|  |  | 15 |  |   Task<Guid?> SchedulerHoldAnyRobotAsync(int realmId); | 
|  |  | 16 |  |   Task<bool> SchedulerHoldRobotAsync(int realmId, Guid robotId); | 
|  |  | 17 |  |   Task SchedulerReleaseRobotAsync(int realmId, Guid robotId); | 
|  |  | 18 |  |   Task AddAutoTaskAsync(int realmId, Guid robotId, RobotClientsAutoTask autoTask); | 
|  |  | 19 |  |   Task AutoTaskHasUpdateAsync(int realmId, AutoTaskUpdate autoTaskUpdate); | 
|  |  | 20 |  | } | 
|  |  | 21 |  |  | 
|  | 0 | 22 |  | public partial class AutoTaskRepository( | 
|  | 0 | 23 |  |     IConnectionMultiplexer redisConnection, | 
|  | 0 | 24 |  |     ILogger<AutoTaskRepository> logger, | 
|  | 0 | 25 |  |     IRobotDataRepository robotDataRepository | 
|  | 0 | 26 |  |   ) : IAutoTaskRepository | 
|  |  | 27 |  | { | 
|  | 0 | 28 |  |   private readonly IConnectionMultiplexer _redisConnection = redisConnection ?? throw new ArgumentNullException(nameof(r | 
|  | 0 | 29 |  |   private readonly IRobotDataRepository _robotDataRepository = robotDataRepository ?? throw new ArgumentNullException(na | 
|  |  | 30 |  |  | 
|  |  | 31 |  |   [LoggerMessage(EventId = 0, Level = LogLevel.Error, Message = "Redis AutoTaskRepository Exception: {Msg}")] | 
|  |  | 32 |  |   public partial void LogException(string msg); | 
|  |  | 33 |  |  | 
|  |  | 34 |  |   public async Task<Guid?> SchedulerHoldAnyRobotAsync(int realmId) | 
|  | 0 | 35 |  |   { | 
|  | 0 | 36 |  |     var db = _redisConnection.GetDatabase(); | 
|  | 0 | 37 |  |     Guid? result = null; | 
|  | 0 | 38 |  |     int robotStatus = (int)RobotStatus.Idle; | 
|  |  | 39 |  |     try | 
|  | 0 | 40 |  |     { | 
|  | 0 | 41 |  |       var search = await db.FT().SearchAsync(RedisHelper.GetRobotDataIndex(realmId), | 
|  | 0 | 42 |  |       new Query($"@{nameof(RobotData.RobotStatus)}:[{robotStatus} {robotStatus}] @{nameof(RobotData.PauseTaskAssignment) | 
|  | 0 | 43 |  |           .Limit(0, 1) | 
|  | 0 | 44 |  |           .ReturnFields(["__key"])); | 
|  | 0 | 45 |  |       string? robotId = search.Documents.FirstOrDefault()?.Id.Replace(RedisHelper.GetRobotDataPrefix(realmId), string.Em | 
|  | 0 | 46 |  |       if (robotId == null) | 
|  | 0 | 47 |  |       { | 
|  | 0 | 48 |  |         return null; | 
|  |  | 49 |  |       } | 
|  | 0 | 50 |  |       if (await db.HashSetAsync(RedisHelper.GetSchedulerHold(realmId, Guid.Parse(robotId)), "Value", "1", When.NotExists | 
|  | 0 | 51 |  |       { | 
|  | 0 | 52 |  |         result = Guid.Parse(robotId); | 
|  | 0 | 53 |  |       } | 
|  | 0 | 54 |  |     } | 
|  | 0 | 55 |  |     catch (Exception ex) | 
|  | 0 | 56 |  |     { | 
|  | 0 | 57 |  |       LogException(ex.Message); | 
|  | 0 | 58 |  |     } | 
|  | 0 | 59 |  |     return result; | 
|  | 0 | 60 |  |   } | 
|  |  | 61 |  |  | 
|  |  | 62 |  |   public async Task<bool> SchedulerHoldRobotAsync(int realmId, Guid robotId) | 
|  | 0 | 63 |  |   { | 
|  | 0 | 64 |  |     var robotData = await _robotDataRepository.GetRobotDataAsync(realmId, robotId); | 
|  | 0 | 65 |  |     if (robotData == null || | 
|  | 0 | 66 |  |         robotData.RobotStatus != RobotStatus.Idle || | 
|  | 0 | 67 |  |         robotData.PauseTaskAssignment == true) | 
|  | 0 | 68 |  |     { | 
|  | 0 | 69 |  |       return false; | 
|  |  | 70 |  |     } | 
|  |  | 71 |  |  | 
|  | 0 | 72 |  |     bool result = false; | 
|  | 0 | 73 |  |     var db = _redisConnection.GetDatabase(); | 
|  |  | 74 |  |     try | 
|  | 0 | 75 |  |     { | 
|  | 0 | 76 |  |       result = await db.HashSetAsync(RedisHelper.GetSchedulerHold(realmId, robotId), "Value", "1", When.NotExists); | 
|  | 0 | 77 |  |     } | 
|  | 0 | 78 |  |     catch (Exception ex) | 
|  | 0 | 79 |  |     { | 
|  | 0 | 80 |  |       LogException(ex.Message); | 
|  | 0 | 81 |  |     } | 
|  | 0 | 82 |  |     return result; | 
|  | 0 | 83 |  |   } | 
|  |  | 84 |  |  | 
|  |  | 85 |  |   public async Task SchedulerReleaseRobotAsync(int realmId, Guid robotId) | 
|  | 0 | 86 |  |   { | 
|  | 0 | 87 |  |     var db = _redisConnection.GetDatabase(); | 
|  |  | 88 |  |     try | 
|  | 0 | 89 |  |     { | 
|  | 0 | 90 |  |       await db.KeyDeleteAsync(RedisHelper.GetSchedulerHold(realmId, robotId)); | 
|  | 0 | 91 |  |     } | 
|  | 0 | 92 |  |     catch (Exception ex) | 
|  | 0 | 93 |  |     { | 
|  | 0 | 94 |  |       LogException(ex.Message); | 
|  | 0 | 95 |  |     } | 
|  | 0 | 96 |  |   } | 
|  |  | 97 |  |  | 
|  |  | 98 |  |   public async Task AddAutoTaskAsync(int realmId, Guid robotId, RobotClientsAutoTask autoTask) | 
|  | 0 | 99 |  |   { | 
|  | 0 | 100 |  |     var subscriber = _redisConnection.GetSubscriber(); | 
|  | 0 | 101 |  |     var data = new RobotClientsResponse { Task = autoTask }; | 
|  | 0 | 102 |  |     var base64 = SerialiserHelper.ToBase64(data); | 
|  |  | 103 |  |     try | 
|  | 0 | 104 |  |     { | 
|  | 0 | 105 |  |       await subscriber.PublishAsync(new RedisChannel(RedisHelper.GetRobotExchangeQueue(robotId), PatternMode.Literal), b | 
|  | 0 | 106 |  |     } | 
|  | 0 | 107 |  |     catch (Exception ex) | 
|  | 0 | 108 |  |     { | 
|  | 0 | 109 |  |       LogException(ex.Message); | 
|  | 0 | 110 |  |     } | 
|  | 0 | 111 |  |   } | 
|  |  | 112 |  |  | 
|  |  | 113 |  |   public async Task AutoTaskHasUpdateAsync(int realmId, AutoTaskUpdate autoTaskUpdate) | 
|  | 0 | 114 |  |   { | 
|  | 0 | 115 |  |     var subscriber = _redisConnection.GetSubscriber(); | 
|  | 0 | 116 |  |     var json = JsonSerializer.Serialize(autoTaskUpdate); | 
|  |  | 117 |  |     try | 
|  | 0 | 118 |  |     { | 
|  | 0 | 119 |  |       await subscriber.PublishAsync(new RedisChannel(RedisHelper.GetAutoTaskUpdateQueue(realmId), PatternMode.Literal),  | 
|  | 0 | 120 |  |     } | 
|  | 0 | 121 |  |     catch (Exception ex) | 
|  | 0 | 122 |  |     { | 
|  | 0 | 123 |  |       LogException(ex.Message); | 
|  | 0 | 124 |  |     } | 
|  | 0 | 125 |  |   } | 
|  |  | 126 |  | } |