2025-01-24 05:45:43 +00:00
|
|
|
using BotSharp.Abstraction.Infrastructures;
|
|
|
|
|
using BotSharp.Abstraction.Statistics.Settings;
|
|
|
|
|
|
|
|
|
|
namespace BotSharp.Core.Statistics.Services;
|
|
|
|
|
|
2025-01-28 00:23:33 +00:00
|
|
|
public class BotSharpStatsService : IBotSharpStatsService
|
2025-01-24 05:45:43 +00:00
|
|
|
{
|
|
|
|
|
private readonly IServiceProvider _services;
|
2025-01-28 00:23:33 +00:00
|
|
|
private readonly ILogger<BotSharpStatsService> _logger;
|
2025-01-24 05:45:43 +00:00
|
|
|
private readonly StatisticsSettings _settings;
|
|
|
|
|
|
|
|
|
|
private const int TIMEOUT_SECONDS = 5;
|
|
|
|
|
|
2025-01-28 00:23:33 +00:00
|
|
|
public BotSharpStatsService(
|
2025-01-24 05:45:43 +00:00
|
|
|
IServiceProvider services,
|
2025-01-28 00:23:33 +00:00
|
|
|
ILogger<BotSharpStatsService> logger,
|
2025-01-24 05:45:43 +00:00
|
|
|
StatisticsSettings settings)
|
|
|
|
|
{
|
|
|
|
|
_services = services;
|
|
|
|
|
_logger = logger;
|
|
|
|
|
_settings = settings;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-28 05:10:37 +00:00
|
|
|
|
|
|
|
|
public bool UpdateStats(string resourceKey, BotSharpStatsInput input)
|
2025-01-24 05:45:43 +00:00
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2025-01-28 05:10:37 +00:00
|
|
|
if (!_settings.Enabled
|
|
|
|
|
|| string.IsNullOrEmpty(resourceKey)
|
|
|
|
|
|| input == null
|
2025-01-28 16:56:45 +00:00
|
|
|
|| string.IsNullOrEmpty(input.Metric)
|
2025-01-28 22:46:59 +00:00
|
|
|
|| string.IsNullOrEmpty(input.Dimension)
|
|
|
|
|
|| input.Data.IsNullOrEmpty())
|
2025-01-28 05:10:37 +00:00
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-24 05:45:43 +00:00
|
|
|
var locker = _services.GetRequiredService<IDistributedLocker>();
|
2025-01-28 05:10:37 +00:00
|
|
|
var res = locker.Lock(resourceKey, () =>
|
2025-01-24 05:45:43 +00:00
|
|
|
{
|
2025-01-28 05:10:37 +00:00
|
|
|
var db = _services.GetRequiredService<IBotSharpRepository>();
|
2025-01-28 22:46:59 +00:00
|
|
|
var body = db.GetGlobalStats(input.Metric, input.Dimension, input.RecordTime, input.IntervalType);
|
2025-01-24 05:45:43 +00:00
|
|
|
if (body == null)
|
|
|
|
|
{
|
2025-01-28 05:10:37 +00:00
|
|
|
var stats = new BotSharpStats
|
|
|
|
|
{
|
2025-01-28 16:56:45 +00:00
|
|
|
Metric = input.Metric,
|
|
|
|
|
Dimension = input.Dimension,
|
2025-01-28 05:10:37 +00:00
|
|
|
RecordTime = input.RecordTime,
|
2025-01-28 22:46:59 +00:00
|
|
|
IntervalType = input.IntervalType,
|
2025-01-28 05:10:37 +00:00
|
|
|
Data = input.Data.ToDictionary(x => x.Key, x => x.Value)
|
|
|
|
|
};
|
2025-01-24 05:45:43 +00:00
|
|
|
db.SaveGlobalStats(stats);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-28 05:10:37 +00:00
|
|
|
foreach (var item in input.Data)
|
2025-01-24 05:45:43 +00:00
|
|
|
{
|
2025-01-24 19:42:17 +00:00
|
|
|
var curValue = item.Value;
|
|
|
|
|
if (body.Data.TryGetValue(item.Key, out var preValue))
|
2025-01-24 05:45:43 +00:00
|
|
|
{
|
2025-01-28 05:10:37 +00:00
|
|
|
switch (item.Operation)
|
2025-01-24 05:45:43 +00:00
|
|
|
{
|
2025-01-28 05:10:37 +00:00
|
|
|
case StatsOperation.Add:
|
|
|
|
|
preValue += curValue;
|
|
|
|
|
break;
|
|
|
|
|
case StatsOperation.Subtract:
|
|
|
|
|
preValue -= curValue;
|
|
|
|
|
break;
|
|
|
|
|
case StatsOperation.Reset:
|
|
|
|
|
preValue = 0;
|
|
|
|
|
break;
|
2025-01-24 05:45:43 +00:00
|
|
|
}
|
2025-01-28 05:10:37 +00:00
|
|
|
body.Data[item.Key] = preValue;
|
2025-01-24 05:45:43 +00:00
|
|
|
}
|
2025-01-28 05:10:37 +00:00
|
|
|
else
|
2025-01-24 05:45:43 +00:00
|
|
|
{
|
2025-01-28 05:10:37 +00:00
|
|
|
body.Data[item.Key] = curValue;
|
2025-01-24 05:45:43 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
db.SaveGlobalStats(body);
|
|
|
|
|
}, TIMEOUT_SECONDS);
|
2025-01-28 05:10:37 +00:00
|
|
|
|
2025-01-24 05:45:43 +00:00
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
2025-01-28 16:56:45 +00:00
|
|
|
_logger.LogError($"Error when updating global stats {input.Metric}-{input.Dimension}. {ex.Message}\r\n{ex.InnerException}");
|
2025-01-24 05:45:43 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|