public EzLockResult(
     LockResult result
     )
 {
     if (result.item != null)
     {
         Item = new EzMutex(result.item);
     }
 }
Ejemplo n.º 2
0
 /// <summary>
 /// 尝试获取分布式锁
 /// </summary>
 /// <returns></returns>
 public virtual LockResult TryGetDistributedLock(TimeSpan?getlockTimeOut, TimeSpan?taskrunTimeOut)
 {
     if (lockresult == LockResult.Success)
     {
         throw new Exception("检测到当前锁已获取");
     }
     lockresult = LockResult.LockSystemExceptionFailure;
     return(lockresult);
 }
        protected LockResult <TSource> TryGetLock <TSource>(RedisClient client, string key, TimeSpan lockAgeTimeout, TimeSpan lockAcquisitionTimeout = new TimeSpan())
        {
            var dlmLock = client.AcquireDlmLock(key, lockAcquisitionTimeout, lockAgeTimeout);

            if (!dlmLock.IsAcquired)
            {
                return(LockResult <TSource> .Fail(key));
            }

            var value = dlmLock.GetValue <TSource>(client);

            return(new LockResult <TSource>(key, true, new LockHandleWrapper(key, dlmLock), value));
        }
Ejemplo n.º 4
0
        public override bool Equals(object o)
        {
            if (this == o)
            {
                return(true);
            }
            if (o == null || this.GetType() != o.GetType())
            {
                return(false);
            }
            LockResult that = ( LockResult )o;

            return(Objects.Equals(_status, that._status) && Objects.Equals(_message, that._message));
        }
        private IActiveLock ValidateLockResult(LockResult result)
        {
            if (result.Lock != null)
            {
                return(result.Lock);
            }

            Debug.Assert(result.ConflictingLocks != null, "result.ConflictingLocks != null");
            foreach (var activeLock in result.ConflictingLocks.GetLocks())
            {
                _output.WriteLine(activeLock.ToString());
            }

            throw new InvalidOperationException("Conflicting locks detected");
        }
Ejemplo n.º 6
0
        public ActionResult Lock(Packet p)
        {
            LockResult result = AssetManager.LockAsset(p.Guid, p.Holder);

            switch (result)
            {
            case LockResult.AlreadyLocked: return(Ok("Already Locked"));

            case LockResult.NotExist: return(NotFound($"guid : {p.Guid} is not exist"));

            case LockResult.Success: return(Ok("Success"));

            default: return(BadRequest($"{result} is not supported"));
            }
        }
            internal ILockState GetLock()
            {
                DateTime dt = DateTime.Now;

                Command = BeginTransactionFor(CreateCommandWith(_createConnection()));

                while (LockResult != LockResult.Acquired)
                {
                    if (MillisecondsPassedFrom(dt) > Timeout)
                    {
                        LockResult = LockResult.AcquisitionTimeout;
                        break;
                    }

                    LockResource();

                    Thread.Sleep(100);
                }

                return(this);
            }
Ejemplo n.º 8
0
        private bool LaunchAfterRestart()
        {
            LockResult result = lockFile.LockWait(10000, WaitRetryDelay);

            while (result != LockResult.Success)
            {
                if (result is LockResult.Fail fail)
                {
                    ShowGenericException(fail);
                    return(false);
                }
                else if (!FormMessage.Warning("TweetDuck Cannot Restart", "TweetDuck is taking too long to close.", FormMessage.Retry, FormMessage.Exit))
                {
                    return(false);
                }

                result = lockFile.LockWait(5000, WaitRetryDelay);
            }

            return(true);
        }
Ejemplo n.º 9
0
        public void ExecuteRead()
        {
            var s = "test";

            m_lock.ExecuteRead(() =>
            {
                s           = "Acquired Read";
                bool result = SyncExecuteOnOtherThread(() => m_lock.ExecuteWrite(() => { throw new Exception("Write was allowed!"); }, TimeSpan.FromMilliseconds(200)));
                result      = SyncExecuteOnOtherThread(() => m_lock.ExecuteUpgradableRead(() => { s = "Acquired Upgradable Read"; }, TimeSpan.FromMilliseconds(200)));
                result.ShouldBeEquivalentTo(true);
            });
            s.ShouldBeEquivalentTo("Acquired Upgradable Read");

            var readResult = m_lock.ExecuteRead(() =>
            {
                s           = "Acquired Read";
                bool result = SyncExecuteOnOtherThread(() => m_lock.ExecuteWrite(() => { throw new Exception("Write was allowed!"); }, TimeSpan.FromMilliseconds(200)));
                result.ShouldBeEquivalentTo(false);
                result = SyncExecuteOnOtherThread(() => m_lock.ExecuteUpgradableRead(() => { s = "Acquired Upgradable Read"; }, TimeSpan.FromMilliseconds(200)));
                result.ShouldBeEquivalentTo(true);
                return("Done");
            });

            LockResult <string> lockReadResult = m_lock.ExecuteRead(() =>
            {
                s           = "Acquired Read";
                bool result = SyncExecuteOnOtherThread(() => m_lock.ExecuteWrite(() => { throw new Exception("Write was allowed!"); }, TimeSpan.FromMilliseconds(200)));
                result      = SyncExecuteOnOtherThread(() => m_lock.ExecuteUpgradableRead(() => { s = "Acquired Upgradable Read"; }, TimeSpan.FromMilliseconds(200)));
                result.ShouldBeEquivalentTo(true);
                return("Done");
            }, TimeSpan.FromSeconds(1));

            lockReadResult.Result.ShouldBeEquivalentTo("Done");
            lockReadResult.State.ShouldBeEquivalentTo(LockResultOutcome.Completed);

            s.ShouldBeEquivalentTo("Acquired Upgradable Read");
            readResult.ShouldBeEquivalentTo("Done");
        }
Ejemplo n.º 10
0
        // Locking

        private bool LaunchNormally()
        {
            LockResult result = lockFile.Lock();

            if (result is LockResult.HasProcess info)
            {
                if (!RestoreProcess(info.Process, WindowRestoreMessage) && FormMessage.Error("TweetDuck is Already Running", "Another instance of TweetDuck is already running.\nDo you want to close it?", FormMessage.Yes, FormMessage.No))
                {
                    if (!CloseProcess(info.Process))
                    {
                        FormMessage.Error("TweetDuck Has Failed :(", "Could not close the other process.", FormMessage.OK);
                        return(false);
                    }

                    info.Dispose();
                    result = lockFile.Lock();
                }
                else
                {
                    return(false);
                }
            }

            if (result is LockResult.Fail fail)
            {
                ShowGenericException(fail);
                return(false);
            }
            else if (result != LockResult.Success)
            {
                FormMessage.Error("TweetDuck Has Failed :(", "An unknown error occurred accessing the data folder. Please, make sure TweetDuck is not already running. If the problem persists, try restarting your system.", FormMessage.OK);
                return(false);
            }

            return(true);
        }
        // When a decorated method is called, this logic will be run instead
        public override void OnInvoke(MethodInterceptionArgs args)
        {
            string key = DeriveCacheKey(args);

            _redisConnStr = ConfigurationManager.AppSettings["redisConnStr"];

            LockResult <MethodTrackerDto> lockResult = new LockResult <MethodTrackerDto>();

            try
            {
                using (var client = new RedisClient(_redisConnStr))
                {
                    lockResult = TryGetLock <MethodTrackerDto>(client, key, _maxMethodLockTime, TimeSpan.FromSeconds(2));

                    if (!lockResult.Acquired)
                    {
                        ReturnWithoutRunning(args);
                    }
                    else
                    {
                        RunMethod(args);
                    }

                    //clear the lock
                    if (lockResult.Handle != null)
                    {
                        lockResult.Handle.Handle.Dispose();
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                ReturnWithoutRunning(args);
            }
        }
 protected internal virtual void LockResource()
 {
     LockResult = (LockResult)Command.ExecuteScalar();
 }
Ejemplo n.º 13
0
        public override void OnInvoke(MethodInterceptionArgs args)
        {
            string key = DeriveCacheKey(args);

            _redisConnStr = ConfigurationManager.AppSettings["redisConnStr"];

            MethodTrackerDto trackerFromDistributedCache = null;
            LockResult <MethodTrackerDto> lockResult     = new LockResult <MethodTrackerDto>();

            try
            {
                MethodTrackerDto trackerFromLocalCache = MemoryCache.Default.Get(key) as MethodTrackerDto;

                //local cache says we can't run this again for a while still due to frequency limits
                if (trackerFromLocalCache != null && trackerFromLocalCache.LastExecuted.HasValue &&
                    trackerFromLocalCache.LastExecuted.Value.Add(_maxMethodFrequencyTime) > DateTime.UtcNow)
                {
                    ReturnWithoutRunning(args);
                    return;
                }

                using (var client = new RedisClient(_redisConnStr))
                {
                    lockResult = TryGetLock <MethodTrackerDto>(client, key, _maxMethodLockTime, TimeSpan.FromSeconds(2));

                    if (!lockResult.Acquired || _maxMethodFrequencyTime == TimeSpan.Zero)
                    {
                        ReturnWithoutRunning(args);
                    }
                    else
                    {
                        trackerFromDistributedCache = lockResult.Result;

                        if (trackerFromDistributedCache == null || trackerFromDistributedCache.LastExecuted == null)
                        {
                            trackerFromDistributedCache = new MethodTrackerDto()
                            {
                                LastExecuted = DateTime.UtcNow
                            };

                            RunMethod(args);
                        }
                        //is the last time plus the interval in the future? If so we can't run it and we can cache that knowledge locally
                        else if (trackerFromDistributedCache.LastExecuted.Value.Add(_maxMethodLockTime) > DateTime.UtcNow)
                        {
                            //cache local since there is a max run. We should have found this locally

                            ReturnWithoutRunning(args);
                        }
                        else
                        {
                            trackerFromDistributedCache = new MethodTrackerDto()
                            {
                                LastExecuted = DateTime.UtcNow
                            };

                            RunMethod(args);
                        }

                        //update local cache in case the method is called again we don't have to hit redis to know we can't run it again yet
                        MemoryCache.Default.Set(key, trackerFromDistributedCache,
                                                trackerFromDistributedCache.LastExecuted.Value.Add(_maxMethodFrequencyTime));
                    }

                    if (trackerFromDistributedCache == null)
                    {
                        trackerFromDistributedCache = new MethodTrackerDto();
                    }
                    trackerFromDistributedCache.LastExecuted = DateTime.UtcNow;

                    //set back to the cache so we track the last time it ran
                    using (var tx = client.CreateTransaction())
                    {
                        tx.QueueCommand(
                            c => c.Set(key, trackerFromDistributedCache, DateTime.UtcNow.Add(_maxMethodFrequencyTime)));
                    }

                    //clear the lock
                    if (lockResult.Handle != null)
                    {
                        //put to the cache the last run time
                        lockResult.Handle.Handle.Dispose();
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                ReturnWithoutRunning(args);
            }
        }
Ejemplo n.º 14
0
        public async Task <UniqueId?> WriteAndUnlockStore(string parentFolderFullName, EmailBackedKeyValueStore?kvStore, LockResult activeLock)
        {
            if (kvStore == null)
            {
                return(UniqueId.Invalid);
            }

            // TODO: improve imap connections; caching etc.
            using var imapClient = await imapConnectionFactory.GetImapConnectionAsync();

            try
            {
                var parentFolder = await imapClient.GetFolderAsync(parentFolderFullName);

                return(await WriteAndUnlockStore(parentFolder, kvStore, activeLock));
            }
            finally
            {
                await imapClient.DisconnectAsync(true);
            }
        }
Ejemplo n.º 15
0
        public async Task <UniqueId?> WriteAndUnlockStore(IMailFolder parentFolder, EmailBackedKeyValueStore?kvStore, LockResult activeLock)
        {
            if (kvStore == null)
            {
                return(UniqueId.Invalid);
            }

            try
            {
                UniqueId?replacementResult = null;
                // TBD review locking
                lock (parentFolder.SyncRoot)
                {
                    parentFolder.Open(FolderAccess.ReadWrite);
                    logger.Debug("Updating existing storage message in folder {FolderPath} with ID {@ID}", parentFolder.FullName, kvStore.MessageAndId.UniqueId);
                    replacementResult = parentFolder.Replace(kvStore.MessageAndId.UniqueId, kvStore.MessageAndId.Message);
                    parentFolder.SetFlags(kvStore.MessageAndId.UniqueId, MessageFlags.Seen, true);
                }
                return(replacementResult);
            }
            finally
            {
                var unlockResult = await remoteLock.ReleaseLock(parentFolder, activeLock.LockResourceName, activeLock.ResultingLockCookie);

                if (!unlockResult)
                {
                    logger.Warning("Could not unlock the following lock: {@LockResult}", activeLock);
                }
            }
        }