与任务执行,新增信号量锁,解决并发环境下数据的一致性问题

This commit is contained in:
yang.lee
2023-11-03 22:12:01 +08:00
parent 669c4228e8
commit 537e54b565
5 changed files with 61 additions and 28 deletions

View File

@@ -54,8 +54,10 @@ namespace Tnb.WarehouseMgr
public class BaseWareHouseService : IOverideVisualDevService, IDynamicApiController, ITransient
{
private static Lazy<Dictionary<string, IWHStorageService>> _stroageMapLazy;
private static Dictionary<string, IWHStorageService> _storeMap = new(StringComparer.OrdinalIgnoreCase);
public OverideVisualDevFunc OverideFuncs { get; } = new OverideVisualDevFunc();
public static SemaphoreSlim s_taskExecuteSemaphore = new SemaphoreSlim(1);
private IEventPublisher _eventPublisher;
@@ -68,10 +70,6 @@ namespace Tnb.WarehouseMgr
/*public BaseWareHouseService(ChannelWriter<NotifyMessage>? channelWriter = default)
{
_channelWriter = channelWriter;
}*/
static BaseWareHouseService()
{

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using JNPF;
using JNPF.Common.Contracts;
using JNPF.Logging;
using Microsoft.Extensions.Logging;
@@ -13,19 +14,35 @@ namespace Tnb.WarehouseMgr
{
public class BaseWareHouseService<T> : BaseWareHouseService
{
protected static Dictionary<string, object> _elevatorMap = new Dictionary<string, object>();
protected static Dictionary<string, object> s_elevatorMap = new Dictionary<string, object>();
private static readonly Lazy<Task> initializationTask;
public BaseWareHouseService(ISqlSugarClient db)
static BaseWareHouseService()
{
if (_elevatorMap.Count < 1)
{
Task.Run(async () =>
{
_elevatorMap = await db.Queryable<WmsElevatorH>().ToDictionaryAsync(x => x.elevator_id, x => x.elevator_code);
});
}
initializationTask = new Lazy<Task>(InitializeAsync);
}
private static async Task InitializeAsync()
{
ConnectionStringsOptions connectionOpts = App.GetConfig<ConnectionStringsOptions>("ConnectionStrings", true);
ConnectionConfig cfg = new()
{
ConfigId = connectionOpts.ConfigId,
ConnectionString = connectionOpts.ConnectString,
DbType = DbType.PostgreSQL,
IsAutoCloseConnection = true,
};
SqlSugarScope context = new(cfg);
s_elevatorMap = await context.Queryable<WmsElevatorH>().ToDictionaryAsync(x => x.elevator_id, x => x.elevator_code);
}
public static Task InitializationTask => initializationTask.Value;
protected ILogger Logger => LoggerFactory.Create(builder => builder.AddFile($"{AppContext.BaseDirectory}/logs/custom{DateTime.Now:yyyyMMdd}.log", cfgOpts =>
{

View File

@@ -61,7 +61,7 @@ namespace Tnb.WarehouseMgr
IEventPublisher eventPublisher,
IUserManager userManger,
IElevatorControlService elevatorControlService
) : base(repository.AsSugarClient())
) //: base(repository.AsSugarClient())
{
_db = repository.AsSugarClient();
_wareHouseService = wareHouseService;
@@ -69,6 +69,7 @@ namespace Tnb.WarehouseMgr
_eventPublisher = eventPublisher;
_userManager = userManger;
_elevatorControlService = elevatorControlService;
_ = InitializationTask;
}
/// <summary>
@@ -111,7 +112,7 @@ namespace Tnb.WarehouseMgr
try
{
Logger.Information($"当前任务Id:{elevator.distask_id}");
if (_elevatorMap.TryGetValue(elevator.device_id, out var elevatorCode))
if (s_elevatorMap.TryGetValue(elevator.device_id, out var elevatorCode))
{
var devName = elevatorCode?.ToString() ?? _eleCtlCfg.DevName;
(int sysStatus, int runStatus, int floorNo, int doorStatus, int agvStatus) = await _elevatorControlService.GetElevatorStatus(devName, CancellationToken.None);
@@ -164,7 +165,7 @@ namespace Tnb.WarehouseMgr
.FirstAsync();
if (elevator.IsNull())
throw new Exception($"根据参数,sourceName:{input.sourceName},taskCode:{input.taskCode},未找到匹配的电梯任务");
if (_elevatorMap.TryGetValue(elevator.elevator_id, out var elevatorCode))
if (s_elevatorMap.TryGetValue(elevator.elevator_id, out var elevatorCode))
{
var devName = elevatorCode?.ToString() ?? _eleCtlCfg.DevName;
(int sysStatus, int runStatus, int floorNo, int doorStatus, int agvStatus) = await _elevatorControlService.GetElevatorStatus(devName, CancellationToken.None);//elevator.elevator_code

View File

@@ -54,7 +54,7 @@ namespace Tnb.WarehouseMgr
public WareHouseService(ISqlSugarRepository<WmsInstockH> repository, IDictionaryDataService dictionaryDataService,
IBillRullService billRullService, IUserManager userManager, ICacheManager cacheManager, IElevatorControlService elevatorControlService)
: base(repository.AsSugarClient())
//: base(repository.AsSugarClient())
{
_db = repository.AsSugarClient();
_dictionaryDataService = dictionaryDataService;
@@ -62,6 +62,7 @@ namespace Tnb.WarehouseMgr
_userManager = userManager;
_cacheManager = cacheManager;
_elevatorControlService = elevatorControlService;
_ = InitializationTask;
}
@@ -215,19 +216,18 @@ namespace Tnb.WarehouseMgr
/// 生成任务执行
/// </summary>
/// <returns></returns>
[HttpPost, Timed(Name = nameof(IWareHouseService.GenTaskExecute))]
[HttpPost]
public async Task GenTaskExecute()
{
await s_taskExecuteSemaphore.WaitAsync();
Stopwatch sw = Stopwatch.StartNew();
CancellationTokenSource agvCts = new();
var db = _db.CopyNew();
try
{
/*if (_elevatorMap.Count < 1)
{
_elevatorMap = await _db.Queryable<WmsElevatorH>().ToDictionaryAsync(x => x.elevator_id, x => x.elevator_code);
}*/
//获取电梯数据
var elevatorList = await db.Queryable<WmsElevatorH>().InnerJoin<WmsElevatorD>((a, b) => a.id == b.bill_id)
.Select((a, b) => new WmsElevatorH
@@ -420,6 +420,7 @@ namespace Tnb.WarehouseMgr
}
finally
{
s_taskExecuteSemaphore.Release();
agvCts.Dispose();
}
}
@@ -436,7 +437,7 @@ namespace Tnb.WarehouseMgr
foreach (var (_, devId, disTaskId, floorNO) in endLocCodes)
{
if (!_elevatorMap.TryGetValue(devId, out var elevatorCode)) continue;
if (!s_elevatorMap.TryGetValue(devId, out var elevatorCode)) continue;
var devName = elevatorCode.ToString();
@@ -510,14 +511,27 @@ namespace Tnb.WarehouseMgr
Logger.Information($"开始执行电梯任务任务ID:{disTask.id}");
try
{
if (!_elevatorMap.TryGetValue(disTask.device_id, out var elevatorCode))
if (!s_elevatorMap.TryGetValue(disTask.device_id, out var elevatorCode))
{
return;
}
var devName = _elevatorMap[disTask.device_id]?.ToString() ?? _eleCtlCfg.DevName;
var devName = s_elevatorMap[disTask.device_id]?.ToString() ?? _eleCtlCfg.DevName;
Logger.Information($"当前:{devName.Match(@"\d+")}#梯");
await _elevatorControlService.WriteTagAsync(devName, ElevatorConsts.AGVControl, 1);
(int sysStatus, int runStatus, int curFloorNo, int doorStatus, int agvStatus) eleStatusMulti = (-1, -1, -1, -1, -1);
if (!_elevatorAgvCtlStatusMap.TryGetValue(disTask.id, out var agvCtlStatus) || agvCtlStatus != (int)EnumAgvStatus.AGV运行状态)
{
do
{
eleStatusMulti = await _elevatorControlService.GetElevatorStatus(devName, CancellationToken.None);
await Task.Delay(500);
} while (eleStatusMulti.agvStatus != (int)EnumAgvStatus.AGV运行状态);
Logger.Information($"{devName.Match(@"\d+")}#, 当前Agv状态:{eleStatusMulti.agvStatus.ToEnum<EnumAgvStatus>().ToString()}");
_elevatorAgvCtlStatusMap[disTask.id] = eleStatusMulti.agvStatus;
}
var doorStatus = -1;
var closeDoorRes = await _elevatorControlService.SendOpenCloseCmd(devName, 4); //向电梯发送前门关门指令
Logger.Information($"关门结果:{closeDoorRes}");

View File

@@ -17,7 +17,9 @@ using JNPF.VisualDev;
using JNPF.VisualDev.Entitys;
using JNPF.VisualDev.Interfaces;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Spire.Doc.Formatting;
using SqlSugar;
using Tnb.BasicData.Entities;
@@ -38,7 +40,7 @@ namespace Tnb.WarehouseMgr
[OverideVisualDev(ModuleConsts.MODULE_WMSEMPTYINSTOCK_ID)]
[ServiceModule(BizTypeId)]
public class WmsEmptyInstockService : BaseWareHouseService, IWmsEmptyInstockService
public class WmsEmptyInstockService : BaseWareHouseService<WmsEmptyInstockService>, IWmsEmptyInstockService
{
private const string BizTypeId = "26121986416677";
private readonly ISqlSugarClient _db;
@@ -64,7 +66,7 @@ namespace Tnb.WarehouseMgr
_wareHouseService = wareHouseService;
_userManager = userManager;
_billRullService = billRullService;
OverideFuncs.CreateAsync = WmsEmptyIn;
}
private async Task<dynamic> WmsEmptyIn(VisualDevModelDataCrInput input)
@@ -189,6 +191,7 @@ namespace Tnb.WarehouseMgr
finally
{
//向队列写入消息
Logger.Information("调用预任务生成");
await InvokeGenPretaskExcute();
}
return Task.FromResult(true);