using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using WIDESEAWCS_S7Simulator.Core.Entities;
using WIDESEAWCS_S7Simulator.Core.Enums;
using WIDESEAWCS_S7Simulator.Core.Interfaces;
using WIDESEAWCS_S7Simulator.Core.Persistence;
using WIDESEAWCS_S7Simulator.Core.Server;
namespace WIDESEAWCS_S7Simulator.Core.Manager
{
///
/// 仿真器实例管理器实现
/// 管理多个S7服务器实例的生命周期,提供线程安全的CRUD操作
///
public class SimulatorInstanceManager : ISimulatorInstanceManager
{
private readonly ConcurrentDictionary _instances = new();
private readonly IPersistenceService _persistenceService;
private readonly ILogger _logger;
private readonly ILoggerFactory _loggerFactory;
///
public event EventHandler? InstanceStateChanged;
///
/// 构造函数
///
/// 持久化服务
/// 日志记录器
/// 日志工厂
public SimulatorInstanceManager(
IPersistenceService persistenceService,
ILogger logger,
ILoggerFactory loggerFactory)
{
_persistenceService = persistenceService ?? throw new ArgumentNullException(nameof(persistenceService));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
}
///
public IReadOnlyList GetAllInstances()
{
return _instances.Values.ToList().AsReadOnly();
}
///
public IS7ServerInstance? GetInstance(string instanceId)
{
if (string.IsNullOrWhiteSpace(instanceId))
{
return null;
}
_instances.TryGetValue(instanceId, out var instance);
return instance;
}
///
public bool InstanceExists(string instanceId)
{
return !string.IsNullOrWhiteSpace(instanceId) && _instances.ContainsKey(instanceId);
}
///
public async Task CreateInstanceAsync(InstanceConfig config)
{
if (config == null)
{
throw new ArgumentNullException(nameof(config));
}
// 如果没有提供ID,生成新的GUID
if (string.IsNullOrWhiteSpace(config.Id))
{
config.Id = Guid.NewGuid().ToString("N");
_logger.LogDebug("为实例生成新ID: {InstanceId}", config.Id);
}
// 检查ID是否已存在
if (_instances.ContainsKey(config.Id))
{
throw new InvalidOperationException($"实例ID {config.Id} 已存在");
}
try
{
// 创建实例
var instanceLogger = _loggerFactory.CreateLogger();
var instance = new S7ServerInstance(config, instanceLogger);
// 添加到字典
if (!_instances.TryAdd(config.Id, instance))
{
throw new InvalidOperationException($"无法将实例 {config.Id} 添加到管理器");
}
// 保存配置
await _persistenceService.SaveInstanceConfigAsync(config);
// 触发状态变化事件
OnInstanceStateChanged(new InstanceStateChangedEventArgs
{
InstanceId = config.Id,
OldStatus = InstanceStatus.Stopped,
NewStatus = InstanceStatus.Stopped,
InstanceState = instance.GetState()
});
_logger.LogInformation("已创建实例 {InstanceId} ({InstanceName})", config.Id, config.Name);
return instance;
}
catch (Exception ex)
{
_logger.LogError(ex, "创建实例 {InstanceId} 时发生错误", config.Id);
throw;
}
}
///
public async Task StartInstanceAsync(string instanceId)
{
if (string.IsNullOrWhiteSpace(instanceId))
{
_logger.LogWarning("尝试启动实例时提供了空ID");
return false;
}
if (!_instances.TryGetValue(instanceId, out var instance))
{
_logger.LogWarning("尝试启动不存在的实例 {InstanceId}", instanceId);
return false;
}
try
{
var oldState = instance.GetState();
var oldStatus = oldState.Status;
// 启动实例
var success = instance.Start();
if (success)
{
var newState = instance.GetState();
// 触发状态变化事件
OnInstanceStateChanged(new InstanceStateChangedEventArgs
{
InstanceId = instanceId,
OldStatus = oldStatus,
NewStatus = newState.Status,
InstanceState = newState
});
_logger.LogInformation("实例 {InstanceId} 已启动", instanceId);
}
else
{
_logger.LogWarning("实例 {InstanceId} 启动失败", instanceId);
}
return success;
}
catch (Exception ex)
{
_logger.LogError(ex, "启动实例 {InstanceId} 时发生异常", instanceId);
return false;
}
}
///
public async Task StopInstanceAsync(string instanceId)
{
if (string.IsNullOrWhiteSpace(instanceId))
{
_logger.LogWarning("尝试停止实例时提供了空ID");
return;
}
if (!_instances.TryGetValue(instanceId, out var instance))
{
_logger.LogWarning("尝试停止不存在的实例 {InstanceId}", instanceId);
return;
}
try
{
var oldState = instance.GetState();
var oldStatus = oldState.Status;
// 停止实例
instance.Stop();
// 同步内存数据到持久化存储
await _persistenceService.SaveMemoryDataAsync(instanceId, instance.MemoryStore);
var newState = instance.GetState();
// 触发状态变化事件
OnInstanceStateChanged(new InstanceStateChangedEventArgs
{
InstanceId = instanceId,
OldStatus = oldStatus,
NewStatus = newState.Status,
InstanceState = newState
});
_logger.LogInformation("实例 {InstanceId} 已停止", instanceId);
}
catch (Exception ex)
{
_logger.LogError(ex, "停止实例 {InstanceId} 时发生异常", instanceId);
}
}
///
public async Task RestartInstanceAsync(string instanceId)
{
if (string.IsNullOrWhiteSpace(instanceId))
{
_logger.LogWarning("尝试重启实例时提供了空ID");
return false;
}
if (!_instances.TryGetValue(instanceId, out var instance))
{
_logger.LogWarning("尝试重启不存在的实例 {InstanceId}", instanceId);
return false;
}
try
{
var oldState = instance.GetState();
var oldStatus = oldState.Status;
// 重启实例
var success = instance.Restart();
if (success)
{
var newState = instance.GetState();
// 触发状态变化事件
OnInstanceStateChanged(new InstanceStateChangedEventArgs
{
InstanceId = instanceId,
OldStatus = oldStatus,
NewStatus = newState.Status,
InstanceState = newState
});
_logger.LogInformation("实例 {InstanceId} 已重启", instanceId);
}
else
{
_logger.LogWarning("实例 {InstanceId} 重启失败", instanceId);
}
return success;
}
catch (Exception ex)
{
_logger.LogError(ex, "重启实例 {InstanceId} 时发生异常", instanceId);
return false;
}
}
///
public async Task DeleteInstanceAsync(string instanceId, bool deleteConfig = true)
{
if (string.IsNullOrWhiteSpace(instanceId))
{
_logger.LogWarning("尝试删除实例时提供了空ID");
return;
}
if (!_instances.TryRemove(instanceId, out var instance))
{
_logger.LogWarning("尝试删除不存在的实例 {InstanceId}", instanceId);
return;
}
try
{
var oldState = instance.GetState();
// 停止实例
instance.Stop();
// 释放实例资源
instance.Dispose();
// 删除配置文件
if (deleteConfig)
{
await _persistenceService.DeleteInstanceConfigAsync(instanceId);
}
// 触发状态变化事件
OnInstanceStateChanged(new InstanceStateChangedEventArgs
{
InstanceId = instanceId,
OldStatus = oldState.Status,
NewStatus = InstanceStatus.Stopped,
InstanceState = oldState
});
_logger.LogInformation("实例 {InstanceId} 已删除", instanceId);
}
catch (Exception ex)
{
_logger.LogError(ex, "删除实例 {InstanceId} 时发生异常", instanceId);
}
}
///
public InstanceState? GetInstanceState(string instanceId)
{
if (string.IsNullOrWhiteSpace(instanceId))
{
return null;
}
if (!_instances.TryGetValue(instanceId, out var instance))
{
return null;
}
return instance.GetState();
}
///
public IReadOnlyList GetAllInstanceStates()
{
return _instances.Values
.Select(i => i.GetState())
.ToList()
.AsReadOnly();
}
///
public async Task LoadSavedInstancesAsync(bool autoStart = true)
{
try
{
_logger.LogInformation("开始加载已保存的实例配置...");
// 加载所有配置
var configs = await _persistenceService.LoadAllInstanceConfigsAsync();
if (configs == null || configs.Count == 0)
{
_logger.LogInformation("没有找到已保存的实例配置");
return;
}
_logger.LogInformation("找到 {Count} 个已保存的实例配置", configs.Count);
foreach (var config in configs)
{
try
{
// 创建实例
var instanceLogger = _loggerFactory.CreateLogger();
var instance = new S7ServerInstance(config, instanceLogger);
// 添加到字典
if (_instances.TryAdd(config.Id, instance))
{
// 加载内存数据
try
{
await _persistenceService.LoadMemoryDataAsync(config.Id, instance.MemoryStore);
_logger.LogDebug("已加载实例 {InstanceId} 的内存数据", config.Id);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "加载实例 {InstanceId} 的内存数据时发生警告", config.Id);
}
// 如果配置了自动启动,则启动实例
if (autoStart && config.AutoStart)
{
_logger.LogInformation("自动启动实例 {InstanceId} ({InstanceName})", config.Id, config.Name);
var success = instance.Start();
if (success)
{
_logger.LogInformation("实例 {InstanceId} 自动启动成功", config.Id);
}
else
{
_logger.LogWarning("实例 {InstanceId} 自动启动失败", config.Id);
}
}
// 触发状态变化事件
OnInstanceStateChanged(new InstanceStateChangedEventArgs
{
InstanceId = config.Id,
OldStatus = InstanceStatus.Stopped,
NewStatus = instance.State.Status,
InstanceState = instance.GetState()
});
_logger.LogInformation("已加载实例 {InstanceId} ({InstanceName})", config.Id, config.Name);
}
else
{
_logger.LogWarning("实例 {InstanceId} 已存在,跳过加载", config.Id);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "加载实例 {InstanceId} 时发生错误", config.Id);
}
}
_logger.LogInformation("实例加载完成,共加载 {Count} 个实例", _instances.Count);
}
catch (Exception ex)
{
_logger.LogError(ex, "加载已保存的实例时发生异常");
}
}
///
public async Task StopAllInstancesAsync()
{
_logger.LogInformation("开始停止所有实例...");
var instanceIds = _instances.Keys.ToList();
foreach (var instanceId in instanceIds)
{
try
{
await StopInstanceAsync(instanceId);
}
catch (Exception ex)
{
_logger.LogError(ex, "停止实例 {InstanceId} 时发生异常", instanceId);
}
}
_logger.LogInformation("所有实例已停止");
}
///
public int GetRunningInstanceCount()
{
return _instances.Values.Count(i => i.State.Status == InstanceStatus.Running);
}
///
public int GetTotalInstanceCount()
{
return _instances.Count;
}
///
/// 触发实例状态变化事件
///
/// 事件参数
protected virtual void OnInstanceStateChanged(InstanceStateChangedEventArgs e)
{
InstanceStateChanged?.Invoke(this, e);
}
}
}