refactor: 修改变量数量限制逻辑

This commit is contained in:
Diego
2025-03-24 14:49:41 +08:00
parent 27d65dd799
commit 492381e4fc
16 changed files with 125 additions and 43 deletions

View File

@@ -402,8 +402,13 @@ public partial class AdminTable<TItem> where TItem : class, new()
[NotNull]
private NavigationManager? NavigationManager { get; set; }
[Parameter]
public Func<Task<TItem>> OnAdd { get; set; }
public Task<TItem> OnAddAsync()
{
if (OnAdd != null)
return OnAdd();
return Task.FromResult(new TItem());
}

View File

@@ -1,8 +1,8 @@
<Project>
<PropertyGroup>
<PluginVersion>10.2.1</PluginVersion>
<ProPluginVersion>10.2.1</ProPluginVersion>
<PluginVersion>10.2.2</PluginVersion>
<ProPluginVersion>10.2.2</ProPluginVersion>
</PropertyGroup>
<PropertyGroup>

View File

@@ -111,11 +111,6 @@ public class ChannelRuntime : Channel, IChannelOptions, IDisposable
public void Init()
{
if (GlobalData.Channels.Count > ThingsGateway.Gateway.Application.DeviceThreadManage.ChannelThreadOptions.MaxChannelCount)
{
throw new Exception($"The number of channels exceeds the limit {ThingsGateway.Gateway.Application.DeviceThreadManage.ChannelThreadOptions.MaxChannelCount}");
}
// 通过插件名称获取插件信息
PluginInfo = GlobalData.PluginService.GetList().FirstOrDefault(A => A.FullName == PluginName);

View File

@@ -219,11 +219,6 @@ public class DeviceRuntime : Device, IDisposable
public void Init(ChannelRuntime channelRuntime)
{
if (GlobalData.Devices.Count > ThingsGateway.Gateway.Application.DeviceThreadManage.ChannelThreadOptions.MaxDeviceCount)
{
throw new Exception($"The number of devices exceeds the limit {ThingsGateway.Gateway.Application.DeviceThreadManage.ChannelThreadOptions.MaxDeviceCount}");
}
ChannelRuntime?.DeviceRuntimes?.TryRemove(Id, out _);
ChannelRuntime = channelRuntime;

View File

@@ -332,10 +332,6 @@ public class VariableRuntime : Variable, IVariable, IDisposable
#endregion
public void Init(DeviceRuntime deviceRuntime)
{
if (GlobalData.IdVariables.Count > ThingsGateway.Gateway.Application.DeviceThreadManage.ChannelThreadOptions.MaxVariableCount)
{
throw new Exception($"The number of variables exceeds the limit {ThingsGateway.Gateway.Application.DeviceThreadManage.ChannelThreadOptions.MaxVariableCount}");
}
GlobalData.AlarmEnableIdVariables.TryRemove(Id, out _);
if (GlobalData.RealAlarmIdVariables.TryRemove(Id, out var oldAlarm))

View File

@@ -54,12 +54,19 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
//事务
var result = await db.UseTranAsync(async () =>
{
ManageHelper.CheckChannelCount(models.Count);
await db.Insertable(models).ExecuteCommandAsync().ConfigureAwait(false);
await db.Insertable(devices.Keys.ToList()).ExecuteCommandAsync().ConfigureAwait(false);
var device = devices.Keys.ToList();
ManageHelper.CheckDeviceCount(device.Count);
await db.Insertable(devices.SelectMany(a => a.Value).ToList()).ExecuteCommandAsync().ConfigureAwait(false);
await db.Insertable(device).ExecuteCommandAsync().ConfigureAwait(false);
var variable = devices.SelectMany(a => a.Value).ToList();
ManageHelper.CheckVariableCount(variable.Count);
await db.Insertable(variable).ExecuteCommandAsync().ConfigureAwait(false);
}).ConfigureAwait(false);
@@ -238,6 +245,8 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
if (type == ItemChangedType.Update)
await GlobalData.SysUserService.CheckApiDataScopeAsync(input.CreateOrgId, input.CreateUserId).ConfigureAwait(false);
ManageHelper.CheckChannelCount(1);
if (await base.SaveAsync(input, type).ConfigureAwait(false))
{
DeleteChannelFromCache();
@@ -292,6 +301,9 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
}
var upData = channels.Where(a => a.IsUp).ToList();
var insertData = channels.Where(a => !a.IsUp).ToList();
ManageHelper.CheckChannelCount(insertData.Count);
using var db = GetDB();
await db.Fastest<Channel>().PageSize(100000).BulkCopyAsync(insertData).ConfigureAwait(false);
await db.Fastest<Channel>().PageSize(100000).BulkUpdateAsync(upData).ConfigureAwait(false);

View File

@@ -57,9 +57,16 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
var result = await db.UseTranAsync(async () =>
{
await db.Insertable(devices.Keys.ToList()).ExecuteCommandAsync().ConfigureAwait(false);
await db.Insertable(devices.SelectMany(a => a.Value).ToList()).ExecuteCommandAsync().ConfigureAwait(false);
var device = devices.Keys.ToList();
ManageHelper.CheckDeviceCount(device.Count);
await db.Insertable(device).ExecuteCommandAsync().ConfigureAwait(false);
var variable = devices.SelectMany(a => a.Value).ToList();
ManageHelper.CheckVariableCount(variable.Count);
await db.Insertable(variable).ExecuteCommandAsync().ConfigureAwait(false);
}).ConfigureAwait(false);
@@ -259,6 +266,9 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
if (type == ItemChangedType.Update)
await GlobalData.SysUserService.CheckApiDataScopeAsync(input.CreateOrgId, input.CreateUserId).ConfigureAwait(false);
ManageHelper.CheckDeviceCount(1);
if (await base.SaveAsync(input, type).ConfigureAwait(false))
{
DeleteDeviceFromCache();
@@ -318,6 +328,9 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
}
var upData = devices.Where(a => a.IsUp).ToList();
var insertData = devices.Where(a => !a.IsUp).ToList();
ManageHelper.CheckDeviceCount(insertData.Count);
using var db = GetDB();
await db.Fastest<Device>().PageSize(100000).BulkCopyAsync(insertData).ConfigureAwait(false);
await db.Fastest<Device>().PageSize(100000).BulkUpdateAsync(upData).ConfigureAwait(false);

View File

@@ -30,17 +30,13 @@ namespace ThingsGateway.Gateway.Application;
/// </summary>
internal sealed class DeviceThreadManage : IAsyncDisposable, IDeviceThreadManage
{
#region
/// <summary>
/// 线程最大等待间隔时间
/// </summary>
public static volatile ChannelThreadOptions ChannelThreadOptions = App.GetOptions<ChannelThreadOptions>();
#region
/// <summary>
/// 线程等待间隔时间
/// </summary>
public static volatile int CycleInterval = ChannelThreadOptions.MaxCycleInterval;
public static volatile int CycleInterval = ManageHelper.ChannelThreadOptions.MaxCycleInterval;
private static IDispatchService<DeviceRuntime> devicelRuntimeDispatchService;
private static IDispatchService<DeviceRuntime> DeviceRuntimeDispatchService
@@ -77,11 +73,11 @@ internal sealed class DeviceThreadManage : IAsyncDisposable, IDeviceThreadManage
//Console.WriteLine($"CPU平均值{avg}");
if (avg > 80)
{
CycleInterval = Math.Max(CycleInterval, (int)(ChannelThreadOptions.MaxCycleInterval * avg / 100));
CycleInterval = Math.Max(CycleInterval, (int)(ManageHelper.ChannelThreadOptions.MaxCycleInterval * avg / 100));
}
else if (avg < 50)
{
CycleInterval = Math.Min(CycleInterval, ChannelThreadOptions.MinCycleInterval);
CycleInterval = Math.Min(CycleInterval, ManageHelper.ChannelThreadOptions.MinCycleInterval);
}
}
}
@@ -588,7 +584,7 @@ internal sealed class DeviceThreadManage : IAsyncDisposable, IDeviceThreadManage
if (driver.CurrentDevice.DeviceStatus == DeviceStatusEnum.OffLine && IsCollectChannel == true)
{
driver.CurrentDevice.CheckEnable = false;
await Task.Delay(Math.Max(Math.Min(((CollectBase)driver).CollectProperties.ReIntervalTime, ChannelThreadOptions.CheckInterval / 2) - CycleInterval, 3000), token).ConfigureAwait(false);
await Task.Delay(Math.Max(Math.Min(((CollectBase)driver).CollectProperties.ReIntervalTime, ManageHelper.ChannelThreadOptions.CheckInterval / 2) - CycleInterval, 3000), token).ConfigureAwait(false);
driver.CurrentDevice.CheckEnable = true;
}
else
@@ -849,7 +845,7 @@ internal sealed class DeviceThreadManage : IAsyncDisposable, IDeviceThreadManage
try
{
//检测设备线程假死
await Task.Delay(ChannelThreadOptions.CheckInterval, cancellationToken).ConfigureAwait(false);
await Task.Delay(ManageHelper.ChannelThreadOptions.CheckInterval, cancellationToken).ConfigureAwait(false);
if (Disposed) return;
var num = Drivers.Count;
@@ -861,7 +857,7 @@ internal sealed class DeviceThreadManage : IAsyncDisposable, IDeviceThreadManage
if (driver.CurrentDevice != null)
{
//线程卡死/初始化失败检测
if (((driver.IsStarted && driver.CurrentDevice.ActiveTime != DateTime.UnixEpoch.ToLocalTime() && driver.CurrentDevice.ActiveTime.AddMinutes(ChannelThreadOptions.CheckInterval) <= DateTime.Now)
if (((driver.IsStarted && driver.CurrentDevice.ActiveTime != DateTime.UnixEpoch.ToLocalTime() && driver.CurrentDevice.ActiveTime.AddMinutes(ManageHelper.ChannelThreadOptions.CheckInterval) <= DateTime.Now)
|| (driver.IsInitSuccess == false)) && !driver.DisposedValue)
{
//如果线程处于暂停状态,跳过

View File

@@ -0,0 +1,47 @@
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://thingsgateway.cn/
// QQ群605534569
//------------------------------------------------------------------------------
namespace ThingsGateway.Gateway.Application;
internal static class ManageHelper
{
/// <summary>
/// 线程最大等待间隔时间
/// </summary>
public static volatile ChannelThreadOptions ChannelThreadOptions = App.GetOptions<ChannelThreadOptions>();
public static void CheckChannelCount(int addCount)
{
if (GlobalData.Channels.Count+ addCount > ManageHelper.ChannelThreadOptions.MaxChannelCount)
{
throw new Exception($"The number of channels exceeds the limit {ManageHelper.ChannelThreadOptions.MaxChannelCount}");
}
}
public static void CheckDeviceCount(int addCount)
{
if (GlobalData.Devices.Count + addCount > ManageHelper.ChannelThreadOptions.MaxDeviceCount)
{
throw new Exception($"The number of devices exceeds the limit {ManageHelper.ChannelThreadOptions.MaxDeviceCount}");
}
}
public static void CheckVariableCount(int addCount)
{
if (GlobalData.IdVariables.Count + addCount > ManageHelper.ChannelThreadOptions.MaxVariableCount)
{
throw new Exception($"The number of variables exceeds the limit {ManageHelper.ChannelThreadOptions.MaxVariableCount}");
}
}
}

View File

@@ -64,6 +64,10 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
// 计算每个设备分配的默认变量数
var groupVariableCount = (int)Math.Ceiling((decimal)variableCount / deviceCount);
ManageHelper.CheckChannelCount(deviceCount);
ManageHelper.CheckDeviceCount(deviceCount);
ManageHelper.CheckVariableCount(variableCount);
for (int i = 0; i < deviceCount; i++)
{
Channel channel = new Channel();
@@ -245,6 +249,8 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
var result = await db.UseTranAsync(async () =>
{
ManageHelper.CheckVariableCount(variables.Count);
await db.Insertable(variables).ExecuteCommandAsync().ConfigureAwait(false);
@@ -279,7 +285,12 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
[OperDesc("SaveVariable", isRecordPar: false, localizerType: typeof(Variable))]
public async Task AddBatchAsync(List<Variable> input)
{
ManageHelper.CheckVariableCount(input.Count);
using var db = GetDB();
var result = await db.Insertable(input).ExecuteCommandAsync().ConfigureAwait(false);
if (result > 0)
@@ -408,6 +419,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
{
if (type == ItemChangedType.Update)
await GlobalData.SysUserService.CheckApiDataScopeAsync(input.CreateOrgId, input.CreateUserId).ConfigureAwait(false);
ManageHelper.CheckVariableCount(1);
if (await base.SaveAsync(input, type).ConfigureAwait(false))
{
@@ -472,6 +484,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
}
var upData = variables.Where(a => a.IsUp).ToList();
var insertData = variables.Where(a => !a.IsUp).ToList();
ManageHelper.CheckVariableCount(insertData.Count);
using var db = GetDB();
await db.Fastest<Variable>().PageSize(100000).BulkCopyAsync(insertData).ConfigureAwait(false);
await db.Fastest<Variable>().PageSize(100000).BulkUpdateAsync(upData).ConfigureAwait(false);

View File

@@ -13,7 +13,7 @@
ShowAdvancedSearch=false
ScrollingDialogContent=false
AllowResizing="true"
CreateItemCallback="CreateItemCallback"
OnAdd="OnAdd"
IsFixedHeader=true
IsMultipleSelect=true
SearchMode=SearchMode.Top

View File

@@ -209,12 +209,12 @@ public partial class VariableRuntimeInfo : IDisposable
#endregion
private VariableRuntime CreateItemCallback()
private Task<VariableRuntime> OnAdd()
{
return new VariableRuntime()
return Task.FromResult(new VariableRuntime()
{
DeviceId = SelectModel?.DeviceRuntime?.Id ?? 0
};
});
}
#region

View File

@@ -3,8 +3,8 @@
"MinCycleInterval": 10, //最小循环间隔
"MaxCycleInterval": 200, //最大循环间隔
"CheckInterval": 1800000, //检查间隔
"MaxChannelCount": 50, //检查间隔
"MaxDeviceCount": 50, //检查间隔
"MaxVariableCount": 10000 //检查间隔
"MaxChannelCount": 50, //最大通道数量
"MaxDeviceCount": 50, //最大设备数量
"MaxVariableCount": 10000 //最大变量数量
}
}

View File

@@ -3,8 +3,8 @@
"MinCycleInterval": 10, //最小循环间隔
"MaxCycleInterval": 200, //最大循环间隔
"CheckInterval": 1800000, //检查间隔
"MaxChannelCount": 1000, //检查间隔
"MaxDeviceCount": 1000, //检查间隔
"MaxVariableCount": 1000000 //检查间隔
"MaxChannelCount": 1000, //最大通道数量
"MaxDeviceCount": 1000, //最大设备数量
"MaxVariableCount": 1000000 //最大变量数量
}
}

View File

@@ -4,11 +4,21 @@
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:5000"
},
"demo": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Demo"
},
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:5000"
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,

View File

@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>10.2.1</Version>
<Version>10.2.2</Version>
</PropertyGroup>
<ItemGroup>