You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
4.4 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
namespace CoreAgent.ProtocolClient.ProtocolEngineCore
{
/// <summary>
/// 管理所有与统计信息相关的操作
/// 职责:
/// 1. 定时轮询获取统计信息 (stats)。
/// 2. 管理统计信息的配置 (samples, rf)。
/// 3. 管理轮询的定时器 (_statsTimer)。
/// 4. 触发统计信息相关的事件。
/// </summary>
public class StatsManager : IDisposable
{
private readonly ILogger _logger;
private readonly Func<JObject, Action<JObject>?, bool, long> _sendMessage;
private readonly string _clientName;
private bool _enableSamples = false;
private bool _enableRf = false;
private int _statsPollDelay = 1000;
private Timer? _statsTimer;
private bool _isFirstStatsUpdate = true;
private bool _disposed = false;
private bool _isConnected = false;
public event EventHandler<JObject>? StatsReceived;
public StatsManager(string clientName, ILogger logger, Func<JObject, Action<JObject>?, bool, long> sendMessage)
{
_clientName = clientName;
_logger = logger;
_sendMessage = sendMessage;
}
public void HandleMessage(JObject message)
{
// The "stats" response is handled via callback in UpdateStats,
// but a generic handler could be placed here if needed in the future.
var messageType = message["message"]?.ToString();
if (messageType == "stats")
{
StatsReceived?.Invoke(this, message);
}
}
public void SetConnectionState(bool isConnected)
{
_isConnected = isConnected;
if (!_isConnected)
{
StopStatsTimer();
}
}
public void TriggerStatsUpdate()
{
UpdateStats();
}
public void ResetStatistics()
{
var resetStats = new JObject { ["cpu"] = new JObject { ["global"] = 0 } };
_logger.LogDebug($"[{_clientName}] 重置统计信息");
// This was a local-only operation in the original code.
// If it needs to send a message, it should be done here.
}
public void SetStatisticsConfig(bool enableSamples, bool enableRf)
{
_enableSamples = enableSamples;
_enableRf = enableRf;
_logger.LogInformation($"[{_clientName}] 设置统计配置: samples={enableSamples}, rf={enableRf}");
}
public (bool samples, bool rf) GetStatisticsConfig()
{
return (_enableSamples, _enableRf);
}
public void SetRefreshDelay(int delay)
{
_statsPollDelay = delay;
}
public void Start(bool first = false)
{
if (first)
{
_isFirstStatsUpdate = true;
}
UpdateStats(first);
}
private void UpdateStats(bool first = false)
{
if (_disposed || !_isConnected) return;
var msg = new JObject { ["message"] = "stats", ["samples"] = _enableSamples, ["rf"] = _enableRf };
_sendMessage(msg, response =>
{
if (_disposed) return;
if (first || _isFirstStatsUpdate)
{
ResetStatistics();
_isFirstStatsUpdate = false;
StartStatsTimer();
// In the original, the first response is not propagated.
return;
}
StatsReceived?.Invoke(this, response);
StartStatsTimer(); // Schedule next update
}, false);
}
private void StartStatsTimer()
{
if (_statsTimer != null) { _statsTimer.Dispose(); }
_statsTimer = new Timer(_ => UpdateStats(), null, _statsPollDelay, Timeout.Infinite);
}
public void StopStatsTimer()
{
_statsTimer?.Dispose();
_statsTimer = null;
}
public void Dispose()
{
if (_disposed) return;
_disposed = true;
StopStatsTimer();
}
}
}