< Summary

Line coverage
0%
Covered lines: 0
Uncovered lines: 105
Coverable lines: 105
Total lines: 263
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 10
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
File 1: .cctor()100%210%
File 2: .ctor(...)0%620%
File 2: IndexExistsAsync()0%620%
File 2: StartExchangeAsync()0%2040%
File 2: StopExchangeAsync()100%210%
File 2: GetRobotDataAsync()100%210%
File 2: SetRobotDataAsync()100%210%
File 2: AddRobotCommandAsync()0%620%

File(s)

/builds/yukaitung/lgdxrobot2-cloud/LGDXRobotCloud.API/obj/Debug/net9.0/Microsoft.Extensions.Logging.Generators/Microsoft.Extensions.Logging.Generators.LoggerMessageGenerator/LoggerMessage.g.cs

File '/builds/yukaitung/lgdxrobot2-cloud/LGDXRobotCloud.API/obj/Debug/net9.0/Microsoft.Extensions.Logging.Generators/Microsoft.Extensions.Logging.Generators.LoggerMessageGenerator/LoggerMessage.g.cs' does not exist (any more).

/builds/yukaitung/lgdxrobot2-cloud/LGDXRobotCloud.API/Repositories/RobotDataRepository.cs

#LineLine coverage
 1using LGDXRobotCloud.Data.Models.Redis;
 2using LGDXRobotCloud.Protos;
 3using LGDXRobotCloud.Utilities.Helpers;
 4using NRedisStack;
 5using NRedisStack.RedisStackCommands;
 6using NRedisStack.Search;
 7using NRedisStack.Search.Literals.Enums;
 8using StackExchange.Redis;
 9using static StackExchange.Redis.RedisChannel;
 10
 11namespace LGDXRobotCloud.API.Repositories;
 12
 13public interface IRobotDataRepository
 14{
 15  // Exchange
 16  Task StartExchangeAsync(int realmId, Guid robotId);
 17  Task StopExchangeAsync(int realmId, Guid robotId);
 18
 19  Task<RobotData?> GetRobotDataAsync(int realmId, Guid robotId);
 20  Task SetRobotDataAsync(int realmId, Guid robotId, RobotData data);
 21
 22  Task<bool> AddRobotCommandAsync(int realmId, Guid robotId, RobotClientsRobotCommands cmd);
 23}
 24
 025public partial class RobotDataRepository(
 026    IConnectionMultiplexer redisConnection,
 027    ILogger<RobotDataRepository> logger
 028  ) : IRobotDataRepository
 29{
 030  private readonly IConnectionMultiplexer _redisConnection = redisConnection ?? throw new ArgumentNullException(nameof(r
 31
 32  [LoggerMessage(EventId = 0, Level = LogLevel.Error, Message = "Redis RobotDataRepository Exception: {Msg}")]
 33  public partial void LogException(string msg);
 34
 35  private async Task<bool> IndexExistsAsync(string indexName)
 036  {
 037    var db = _redisConnection.GetDatabase();
 38    try
 039    {
 040      var index = await db.FT().InfoAsync(indexName);
 041    }
 042    catch (Exception ex)
 043    {
 044      if (!ex.Message.Contains("Unknown index name", StringComparison.CurrentCultureIgnoreCase))
 045      {
 046        LogException(ex.Message);
 047      }
 048      return false;
 49    }
 050    return true;
 051  }
 52
 53  public async Task StartExchangeAsync(int realmId, Guid robotId)
 054  {
 055    var db = _redisConnection.GetDatabase();
 56
 57    // Create index
 058    if (!await IndexExistsAsync(RedisHelper.GetRobotDataIndex(realmId)))
 059    {
 60      try
 061      {
 062        await db.FT().CreateAsync(RedisHelper.GetRobotDataIndex(realmId),
 063          new FTCreateParams()
 064            .On(IndexDataType.JSON)
 065            .Prefix(RedisHelper.GetRobotDataPrefix(realmId)),
 066          new Schema()
 067          .AddNumericField(new FieldName($"$.{nameof(RobotData.RobotStatus)}", $"{nameof(RobotData.RobotStatus)}"))
 068          .AddTagField(new FieldName($"$.{nameof(RobotData.PauseTaskAssignment)}", $"{nameof(RobotData.PauseTaskAssignme
 069      }
 070      catch (Exception ex)
 071      {
 072        if (!ex.Message.Contains("Index already exists", StringComparison.CurrentCultureIgnoreCase))
 073        {
 074          LogException(ex.Message);
 075        }
 076      }
 077    }
 78    try
 079    {
 080      await db.JSON().SetAsync(RedisHelper.GetRobotData(realmId, robotId), "$", new RobotData());
 081      await db.KeyExpireAsync(RedisHelper.GetRobotData(realmId, robotId), TimeSpan.FromMinutes(5));
 082    }
 083    catch (Exception ex)
 084    {
 085      LogException(ex.Message);
 086    }
 087  }
 88
 89  public async Task StopExchangeAsync(int realmId, Guid robotId)
 090  {
 091    var db = _redisConnection.GetDatabase();
 92    try
 093    {
 094      await db.KeyDeleteAsync(RedisHelper.GetRobotData(realmId, robotId));
 095    }
 096    catch (Exception ex)
 097    {
 098      LogException(ex.Message);
 099    }
 0100  }
 101
 102  public async Task<RobotData?> GetRobotDataAsync(int realmId, Guid robotId)
 0103  {
 0104    var db = _redisConnection.GetDatabase();
 0105    RobotData? result = null;
 106    try
 0107    {
 0108      result = await db.JSON().GetAsync<RobotData>(RedisHelper.GetRobotData(realmId, robotId));
 0109    }
 0110    catch (Exception ex)
 0111    {
 0112      LogException(ex.Message);
 0113    }
 0114    return result;
 0115  }
 116
 117  public async Task SetRobotDataAsync(int realmId, Guid robotId, RobotData data)
 0118  {
 0119    var db = _redisConnection.GetDatabase();
 0120    var pipeline = new Pipeline(db);
 0121    List<Task> tasks = [];
 122    try
 0123    {
 0124      tasks.Add(pipeline.Json.SetAsync(RedisHelper.GetRobotData(realmId, robotId), "$", data));
 0125      tasks.Add(db.KeyExpireAsync(RedisHelper.GetRobotData(realmId, robotId), TimeSpan.FromMinutes(5)));
 0126      pipeline.Execute();
 0127      await Task.WhenAll(tasks);
 0128    }
 0129    catch (Exception ex)
 0130    {
 0131      LogException(ex.Message);
 0132    }
 0133  }
 134
 135  public async Task<bool> AddRobotCommandAsync(int realmId, Guid robotId, RobotClientsRobotCommands cmd)
 0136  {
 0137    var db = _redisConnection.GetDatabase();
 138    try
 0139    {
 0140      if (!await db.KeyExistsAsync(RedisHelper.GetRobotData(realmId, robotId)))
 0141      {
 0142        return false;
 143      }
 0144      var subscriber = _redisConnection.GetSubscriber();
 0145      var data = new RobotClientsResponse { Commands = cmd };
 0146      var base64 = SerialiserHelper.ToBase64(data);
 0147      await subscriber.PublishAsync(new RedisChannel(RedisHelper.GetRobotExchangeQueue(robotId), PatternMode.Literal), b
 0148      return true;
 149    }
 0150    catch (Exception ex)
 0151    {
 0152      LogException(ex.Message);
 0153    }
 0154    return false;
 0155  }
 156}