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);
            }
        }
Esempio n. 5
0
 /// <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);
        }