Пример #1
0
        private MemoryLockStatus TryAcquireResources(MemoryLock memoryLock)
        {
            //这里可以不加锁,因为已经上了资源锁

            long now = TimeUtil.UtcNowUnixTimeMilliseconds;

            for (int i = 0; i < memoryLock.ResourceKeys.Count; ++i)
            {
                string resourceKey = memoryLock.ResourceKeys[i];

                //不存在 or 存在但已经过期,因为MemoryCache并不能即使的清除过期,所以也得检查
                if (!_memoryCache.TryGetValue(resourceKey, out MemoryLockResourceExpiryInfo storedInfo) || now - storedInfo.Timestamp >= storedInfo.ExpiryMilliseconds)
                {
                    _memoryCache.Set(
                        resourceKey,
                        new MemoryLockResourceExpiryInfo(now, (long)memoryLock.ExpiryTime.TotalMilliseconds, memoryLock.ResourceValues[i]),
                        memoryLock.ExpiryTime);

                    continue;
                }
                else
                {
                    //存在且不过期
                    return(MemoryLockStatus.Failed);
                }
            }

            return(MemoryLockStatus.Acquired);
        }
Пример #2
0
        private void ExtendLockLifetime(MemoryLock memoryLock)
        {
            if (memoryLock.Status != MemoryLockStatus.Acquired)
            {
                _logger.LogDebug(
                    "锁已不是获取状态,停止自动延期... {ThreadID}, {ResourceKeys}, {Status}",
                    Thread.CurrentThread.ManagedThreadId, memoryLock.ResourceKeys, memoryLock.Status);
                return;
            }

            memoryLock.ExtendCount++;

            long now = TimeUtil.UtcNowUnixTimeMilliseconds;

            for (int i = 0; i < memoryLock.ResourceKeys.Count; ++i)
            {
                if (_memoryCache.TryGetValue(memoryLock.ResourceKeys[i], out MemoryLockResourceExpiryInfo storedInfo) && storedInfo.ResourceValue == memoryLock.ResourceValues[i])
                {
                    _memoryCache.Set(
                        memoryLock.ResourceKeys[i],
                        new MemoryLockResourceExpiryInfo(now, (long)memoryLock.ExpiryTime.TotalMilliseconds, memoryLock.ResourceValues[i]),
                        memoryLock.ExpiryTime);
                }
            }
        }
Пример #3
0
 internal static void StopKeepAliveTimer(MemoryLock memoryLock)
 {
     if (memoryLock.KeepAliveTimer != null)
     {
         memoryLock.KeepAliveTimer.Change(Timeout.Infinite, Timeout.Infinite);
         memoryLock.KeepAliveTimer.Dispose();
         memoryLock.KeepAliveTimer = null;
     }
 }
Пример #4
0
        private void StartAutoExtendTimer(MemoryLock memoryLock)
        {
            long interval = (long)memoryLock.ExpiryTime.TotalMilliseconds / 2;

            memoryLock.KeepAliveTimer = new Timer(
                state => { ExtendLockLifetime(memoryLock); },
                null,
                interval,
                interval);
        }
Пример #5
0
        internal void Unlock(MemoryLock memoryLock)
        {
            //这里不加锁也没关系,因为不影响上面Acquire时的三个判断
            //比如:判断“存在但过期”,这里删掉了。不影响

            StopKeepAliveTimer(memoryLock);

            for (int i = 0; i < memoryLock.ResourceKeys.Count; ++i)
            {
                if (_memoryCache.TryGetValue(memoryLock.ResourceKeys[i], out MemoryLockResourceExpiryInfo storedInfo) && storedInfo.ResourceValue == memoryLock.ResourceValues[i])
                {
                    _memoryCache.Remove(memoryLock.ResourceKeys[i]);
                }
            }

            memoryLock.Status = MemoryLockStatus.Disposed;
        }
Пример #6
0
        public IMemoryLock Lock(string resourceType, IEnumerable <string> resources, TimeSpan expiryTime, TimeSpan?waitTime = null, CancellationToken cancellationToken = default)
        {
            if (waitTime == null)
            {
                waitTime = _options.DefaultWaitTime;
            }

            MemoryLock memoryLock = new MemoryLock(this, resourceType, resources, expiryTime);

            SemaphoreSlim semaphore = _resourceTypeSemaphoreDict.GetOrAdd(resourceType, new SemaphoreSlim(1, 1));

            Stopwatch stopwatch = Stopwatch.StartNew();

            if (semaphore.Wait(waitTime.Value, cancellationToken))
            {
                try
                {
                    if (waitTime != TimeSpan.Zero)
                    {
                        //可以等待
                        while (!memoryLock.IsAcquired && stopwatch.Elapsed <= waitTime)
                        {
                            memoryLock.Status = TryAcquireResources(memoryLock);

                            if (!memoryLock.IsAcquired)
                            {
#pragma warning disable VSTHRD002 // Avoid problematic synchronous waits
                                Task.Delay(_options.DefaultRetryIntervalMilliseconds, cancellationToken).Wait(cancellationToken);
#pragma warning restore VSTHRD002 // Avoid problematic synchronous waits
                            }
                        }

                        if (!memoryLock.IsAcquired)
                        {
                            memoryLock.Status = MemoryLockStatus.Expired;
                        }
                    }
                    else
                    {
                        //不等待
                        memoryLock.Status = TryAcquireResources(memoryLock);
                    }
                }
                finally
                {
                    semaphore.Release();
                }

                if (memoryLock.IsAcquired)
                {
                    StartAutoExtendTimer(memoryLock);
                }
            }
            else
            {
                memoryLock.Status = MemoryLockStatus.ResourceTypeSemaphoreExpired;
            }

            stopwatch.Stop();

            return(memoryLock);
        }