7.8 KiB
source_files, generated_at, model, schema_version, sha256
| source_files | generated_at | model | schema_version | sha256 | |||
|---|---|---|---|---|---|---|---|
|
2026-04-16T11:44:27.973248+00:00 | zai-org/GLM-5-FP8 | 1 | 95ed39e21f5416a3 |
Documentation: DTS.Common.Import.DatabaseLocks
1. Purpose
This module provides a concurrency control mechanism for the import process, ensuring that database entities (Groups, TestSetups, and Sensors) are not modified by multiple users simultaneously. It implements the ILockImport interface to manage the lifecycle of database locks: acquiring them before an import operation, detecting contention (locks held by other users), handling "stranded" locks (expired locks), and releasing locks upon completion. It enforces permissions for lock stealing, restricting the ability to forcefully take locks to administrative users.
2. Public Interface
The module consists of three concrete classes, all implementing ILockImport.
Class: LockImportGroups
Manages locking for static group entities.
- Constructor:
LockImportGroups(User currentUser, double strandedLockTimeoutMinutes)- Initializes the locker with the user context and the threshold for considering a lock "stranded" (expired).
- Property:
bool Contended- Returns
trueif any group attempted to be locked is currently held by another user; otherwisefalse.
- Returns
- Method:
void FreeLock(ref ImportObject importObject)- Releases all groups currently stored in the internal
_lockedGroupslist by callingLockManager.FreeLock. Note that theimportObjectparameter is ignored in the implementation.
- Releases all groups currently stored in the internal
- Method:
void SetLock(ref ImportObject importObject, ref StringBuilder message)- Iterates over
importObject.StaticGroups(). Attempts to lock each group. - If a lock fails because the item is not found (
LockError.ITEM_NOT_FOUND), it skips the item. - If a lock is held by the current user (matching
UserNameandMachineName) or is expired (LastUpdated+_strandedLockTimeoutMinutes<DateTime.Now), it forcefully claims the lock. - Populates
_contendedGroupsif locks are held by others. Appends contention details to themessageStringBuilder.
- Iterates over
- Method:
bool StealLock(bool proceed)- Attempts to forcefully take locks listed in
_contendedGroups. - Returns
falseif locks are contended and the user is not an Admin (!_currentUser.IsAdmin). - Returns
falseif locks are contended andproceedisfalse. - Returns
trueif no contention exists or if the steal operation proceeds successfully.
- Attempts to forcefully take locks listed in
Class: LockImportTestSetups
Manages locking for test setup entities.
- Constructor:
LockImportTestSetups(User currentUser, double strandedLockTimeoutMinutes) - Property:
bool Contended- Returns
trueif_contendedTestscontains any items.
- Returns
- Method:
void FreeLock(ref ImportObject importObject)- Releases locks for items in
_lockedTests.
- Releases locks for items in
- Method:
void SetLock(ref ImportObject importObject, ref StringBuilder message)- Iterates over
importObject.TestSetups(). Logic mirrorsLockImportGroupsregarding expiration, ownership checks, and contention handling.
- Iterates over
- Method:
bool StealLock(bool proceed)- Logic mirrors
LockImportGroupsregarding Admin checks and theproceedflag.
- Logic mirrors
Class: LockImportSensors
Manages locking for sensor entities.
- Constructor:
LockImportSensors(User currentUser, double strandedLockTimeoutMinutes) - Property:
bool Contended- Returns
trueif_contendedSensorscontains any items.
- Returns
- Method:
void FreeLock(ref ImportObject importObject)- Releases locks for items in
_lockedSensors.
- Releases locks for items in
- Method:
void SetLock(ref ImportObject importObject, ref StringBuilder message)- Difference from other classes: It first retrieves all sensors via
SensorsCollection.SensorsList.GetAllSensors(true)and creates a dictionary lookup. - Iterates
importObject.Sensors(). Skips locking if the serial number is not found in the lookup. - Logic mirrors other classes for handling existing/expired locks.
- Difference from other classes: It first retrieves all sensors via
- Method:
bool StealLock(bool proceed)- Logic mirrors
LockImportGroupsregarding Admin checks and theproceedflag.
- Logic mirrors
3. Invariants
- Admin Requirement for Stealing: The
StealLockmethod will always returnfalseif_contendedGroups(or equivalent) is populated and_currentUser.IsAdminisfalse. - Lock Ownership Identity: A lock is considered "owned" by the current user in
SetLockonly if bothexistingLock.LockingUserNamematches_currentUser.UserNameANDexistingLock.LockingMachineNamematchesEnvironment.MachineName. - State Reset: Calling
SetLockalways clears the internal locked and contended lists (_lockedGroups,_contendedGroups, etc.) before processing new locks. - Stranded Lock Calculation: A lock is considered stranded/eligible for reclamation if
existingLock.LastUpdated.AddMinutes(_strandedLockTimeoutMinutes) < DateTime.Now. - Exception Handling: In
SetLockmethods, if an exception occurs during the locking loop for a specific item, it is logged viaAPILogger.Log(ex)and the loop continues to the next item; the import process is not halted by a single locking failure.
4. Dependencies
Internal Dependencies (Referenced in Source)
DTS.Common.Classes.Locking: ProvidesLockManager,LockRecord,LockError.DTS.Common.Import.Interfaces: DefinesILockImport.DTS.Common.SharedResource.Strings: ProvidesStringResourcesfor user messages.DTS.Common.Storage: Likely definesImportObject.DTS.Common.Utilities.Logging: ProvidesAPILogger.DTS.Slice.Users: Provides theUserclass.DTS.SensorDB: ProvidesSensorsCollection(used specifically inLockImportSensors).
External Dependencies (Inferred)
System,System.Collections.Generic,System.Linq,System.Text.
Dependents
- Unknown from source alone. Presumably, an Import Manager or Controller class instantiates these lockers to orchestrate import operations.
5. Gotchas
-
Incorrect Item Category in
StealLock(Bug): In bothLockImportGroups.StealLockandLockImportTestSetups.StealLock, the code callsLockManager.LockItemwithLockManager.ItemCategories.Sensor.- Source Evidence:
LockImportGroups.csline 93 andLockImportTestSetups.csline 90. - Impact: When stealing a lock for a Group or TestSetup, the new lock is incorrectly recorded in the database with the "Sensor" category.
LockImportSensorsuses the correct category.
- Source Evidence:
-
Incorrect Error Message in
LockImportSensors: InLockImportSensors.SetLock, when appending contention details to the message, the code usesStringResources.ImportTestSetup_TestsLocked.- Source Evidence:
LockImportSensors.csline 76. - Impact: Users importing sensors will receive an error message intended for Test Setups.
- Source Evidence:
-
Unused Parameter in
FreeLock: TheFreeLockmethod signature includesref ImportObject importObject, but the implementation in all three classes ignores this parameter entirely. It relies strictly on the internal list (_lockedGroups, etc.) populated duringSetLock. Passing a differentImportObjecttoFreeLockthan was passed toSetLockwill have no effect; the locks released are determined solely by the previousSetLockcall. -
Silent Failures: The
SetLockmethods catch all exceptions, log them, and continue. IfLockManagerthrows an unexpected exception (e.g., database connection failure), the import process will proceed for remaining items, potentially resulting in a partial lock state without a clear indication to the caller other than the log file.