| | 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 | | } |