private LockResource CreateResource(string resourceId) { LockResource resource = new LockResource(resourceId); resource.LockGranted += OnLockGranted; return(resource); }
/// <summary> /// Enqueues a lock request for the specified resource. /// </summary> /// <param name="requestId">The unique identifier for the request.</param> /// <param name="resourceId">The resource identifier.</param> /// <param name="requestName">The name to use for identifying the request.</param> protected void RequestLock(Guid requestId, string resourceId, string requestName) { // Create a new lock request and add it to the list of all requests. LockRequest request = new LockRequest(requestId, requestName); _allRequests.TryAdd(request.RequestId, request); // Find (or create) the resource and enqueue the request. LockResource resource = GetResource(resourceId); resource.AddRequest(request); }
/// <summary> /// Enqueues a lock request for the specified resource. /// </summary> /// <param name="requestId">The unique identifier for the request.</param> /// <param name="resourceIds">The list of resource identifiers.</param> /// <param name="requestName">The name to use for identifying the request.</param> /// <exception cref="ArgumentNullException"><paramref name="resourceIds" /> is null.</exception> protected void RequestLock(Guid requestId, IEnumerable <string> resourceIds, string requestName) { if (resourceIds == null) { throw new ArgumentNullException(nameof(resourceIds)); } // Create a new lock request and add it to the list of all requests. LockRequest request = new LockRequest(requestId, requestName); _allRequests.TryAdd(request.RequestId, request); // Find (or create) each resource and enqueue the request. foreach (string resourceId in resourceIds) { LockResource resource = GetResource(resourceId); resource.AddRequest(request); } }
/// <summary> /// Cancels the lock request with the specified request ID. /// </summary> /// <param name="requestId">The lock request identifier.</param> protected void CancelRequest(Guid requestId) { LockResource resource = null; // Retrieve and remove the lock request from the list of all requests. if (_allRequests.TryRemove(requestId, out LockRequest request)) { lock (request) { // There could be a race condition where the client cancels the request just after // the server grants the lock. Check to see if the lock has already been granted. // If it has, the lock will be cleaned up via a regular release below. // (The actual release must happen outside of the locked region or a deadlock will occur.) if (request.State == LockRequestState.Granted) { if (_activeLocks.TryRemove(requestId, out resource)) { LogWarn($"Request '{request.Name}' released lock for resource '{resource.ResourceId}' via cancellation."); } } else { // Once the request is flagged as "Canceled" it will be ignored by any resources that are tracking it. // Eventually it will fall out of each queue and be garbage collected. request.State = LockRequestState.Canceled; LogTrace($"Request '{request.Name}' was canceled."); } } } // Resource will be non-null only if the lock needs to be released. if (resource != null) { resource.ReleaseLock(request); } }
/// <summary> /// Initializes a new instance of the <see cref="LockGrantedEventArgs" /> class. /// </summary> /// <param name="lockRequest">The <see cref="LockRequest" /> that has been granted.</param> /// <param name="resource">The <see cref="LockResource"/> that has been given to the requester.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="lockRequest" /> is null. /// <para>or</para> /// <paramref name="resource" /> is null.</exception> public LockGrantedEventArgs(LockRequest lockRequest, LockResource resource) { Request = lockRequest ?? throw new ArgumentNullException(nameof(lockRequest)); Resource = resource ?? throw new ArgumentNullException(nameof(resource)); }
/// <summary> /// Sets the maximum number of consumers that can use the specified resource concurrently. /// </summary> /// <param name="resourceId">The resource identifier.</param> /// <param name="maxConcurrent">The maximum number of consumers that can use the specified resource concurrently.</param> /// <exception cref="ArgumentNullException"><paramref name="resourceId" /> is null.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="maxConcurrent" /> is less than or equal to zero.</exception> protected void SetConcurrency(string resourceId, int maxConcurrent) { LockResource resource = GetResource(resourceId); resource.SetConcurrency(maxConcurrent); }