Files
DP44/Common/DTS.Common.Import/DatabaseLocks/LockImportTestSetups.cs
2026-04-17 14:55:32 -04:00

133 lines
5.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DTS.Common.Classes.Locking;
using DTS.Common.Import.Interfaces;
using DTS.Common.SharedResource.Strings;
using DTS.Common.Storage;
using DTS.Common.Utilities.Logging;
using DTS.Slice.Users;
namespace DTS.Common.Import.DatabaseLocks
{
//FB 36740
public class LockImportTestSetups : ILockImport
{
private readonly User _currentUser;
private readonly double _strandedLockTimeoutMinutes;
/// <summary>
/// this is a list of all tests locked by user
/// </summary>
private readonly List<LockRecord> _lockedTests = new List<LockRecord>();
/// <summary>
/// this is a list of tests locking was attempted but another user has the lock
/// </summary>
private readonly List<LockRecord> _contendedTests = new List<LockRecord>();
public LockImportTestSetups(User currentUser, double strandedLockTimeoutMinutes)
{
_currentUser = currentUser;
_strandedLockTimeoutMinutes = strandedLockTimeoutMinutes;
}
public bool Contended { get => _contendedTests.Any(); }
public void FreeLock(ref ImportObject importObject)
{
if (!_lockedTests.Any())
{
return;
}
foreach (var record in _lockedTests)
{
LockManager.FreeLock(record.ItemId, _currentUser.UserName, _currentUser.Id, out var lockError, record.ItemCategory);
}
}
public void SetLock(ref ImportObject importObject, ref StringBuilder message)
{
_lockedTests.Clear();
_contendedTests.Clear();
foreach (var test in importObject.TestSetups())
{
try
{
var gotLock = LockManager.LockItem(test.Name, test.Id, LockManager.ItemCategories.TestSetup, _currentUser.UserName,
_currentUser.Id, out var existingLock, out var lockError);
if (!gotLock)
{
if (lockError.ErrorCode == LockError.ITEM_NOT_FOUND)
{
continue; //lock not needed, doesn't exist in db
}
var lockOutOfDate = existingLock.LastUpdated.AddMinutes(_strandedLockTimeoutMinutes) < DateTime.Now;
var IHaveTheLock = existingLock.LockingUserName == _currentUser.UserName && existingLock.LockingMachineName == Environment.MachineName;
if (lockOutOfDate || IHaveTheLock)
{
//lock is expired (or already belongs to us), either way we can claim it
_ = LockManager.FreeLock(existingLock.ItemId, _currentUser.UserName, _currentUser.Id, out lockError, existingLock.ItemCategory);
_ = LockManager.LockItem(existingLock.ItemKey, existingLock.ItemId, LockManager.ItemCategories.TestSetup, _currentUser.UserName,
_currentUser.Id, out existingLock, out lockError);
_lockedTests.Add(existingLock);
}
else
{
//couldn't be locked, we need Admin + confirmation to steal lock
_contendedTests.Add(existingLock);
}
}
else
{
//successfully locked
_lockedTests.Add(existingLock);
}
}
catch (Exception ex) { APILogger.Log(ex); }
}
if (!_contendedTests.Any())
{
return;
}
message.AppendLine(StringResources.ImportTestSetup_TestsLocked);
foreach (var contended in _contendedTests)
{
message.AppendLine($"{contended.ItemKey} by {contended.LockingUserName} on {contended.LockingMachineName}");
}
}
public bool StealLock(bool proceed)
{
if (!_contendedTests.Any())
{
return true;
}
if (!_currentUser.IsAdmin)
{
return false;
}
//steal locks if user oks it
if (!proceed)
{
return false;
}
foreach (var contendedTest in _contendedTests)
{
LockManager.FreeLock(contendedTest.ItemId, _currentUser.UserName, _currentUser.Id, out var lockError, contendedTest.ItemCategory);
LockManager.LockItem(contendedTest.ItemKey, contendedTest.ItemId, LockManager.ItemCategories.Sensor, _currentUser.UserName, _currentUser.Id, out var newLockRecord, out lockError);
_lockedTests.Add(newLockRecord);
}
return true;
}
}
}