コード例 #1
0
ファイル: Program.cs プロジェクト: alandoherty/tandem-net
        static async void A2(ILockManager manager)
        {
            // wait one second
            await Task.Delay(1000);

            // check if it's locked
            LockToken existingLock = await manager.QueryAsync("tandem://devices/Wow");

            if (existingLock.IsValid)
            {
                Console.WriteLine($"It's locked by '{existingLock.Owner}'");
            }

            // now try and obtain a lock
            await Task.Delay(2000);

            using (var h = await manager.LockAsync("tandem://devices/wow")) {
                if (h == null)
                {
                    Console.WriteLine("Couldn't get a lock!");
                }
                else
                {
                    Console.WriteLine("Got a lock!");
                    ProceedSemaphore.Release();
                }
            }
        }
コード例 #2
0
        public void UT_LockToken_ToString_LockTokenHeaderWithSquaredBrackets()
        {
            var lockToken = new LockToken("<my-lock-token>");
            var str       = lockToken.ToString(LockTokenFormat.LockTokenHeader);

            Assert.AreEqual("<my-lock-token>", str);
        }
コード例 #3
0
ファイル: Djin.cs プロジェクト: Zerq/SakuraBlue
        public Djin(LockToken token) : base(token)
        {
            rates = new Dictionary <Type, float>()
            {
                { typeof(Stats.DarkStat), 1.1f },
                { typeof(Stats.LightStat), 1f },
                { typeof(Stats.ChaosStat), 1.1f },
                { typeof(Stats.Orderstat), 1f },
                { typeof(Stats.FireStat), 1.2f },
                { typeof(Stats.WaterStat), 1f },
                { typeof(Stats.EarthStat), 1f },
                { typeof(Stats.WindStat), 1f },
            };

            statBonuse = new Dictionary <Type, int>()
            {
                { typeof(Stats.DarkStat), 1 },
                { typeof(Stats.LightStat), 0 },
                { typeof(Stats.ChaosStat), 1 },
                { typeof(Stats.Orderstat), 0 },
                { typeof(Stats.FireStat), 2 },
                { typeof(Stats.WaterStat), 0 },
                { typeof(Stats.EarthStat), 0 },
                { typeof(Stats.WindStat), 0 },
            };
        }
コード例 #4
0
        public async Task <Tuple <IEnumerable <Event>, bool> > TryScheduleAsync(DiagnosticsSource source)
        {
            // if Stop offset has been reached
            if (!string.IsNullOrEmpty(source.StopOffsetPoint) && source.LastOffsetPoint != null && source.LastOffsetPoint.CompareTo(source.StopOffsetPoint) >= 0)
            {
                return(new Tuple <IEnumerable <Event>, bool>(Enumerable.Empty <Event>(), false));
            }

            var lockToken = new LockToken(source.ToTypeKey());
            int seconds   =
                Convert.ToInt32(_configurationValueProvider.GetValue(ConfigurationKeys.ClusterLockDurationSeconds));

            if (!(await _lockStore.TryLockAsync(lockToken, 2, 1000, seconds * 1000)))
            {
                TheTrace.TraceInformation("I could NOT be master for {0}", source.ToTypeKey());
                return(new Tuple <IEnumerable <Event>, bool>(Enumerable.Empty <Event>(), false));
            }
            try
            {
                var events = await DoSchedule(source);

                return(new Tuple <IEnumerable <Event>, bool>(events, true));
            }
            finally
            {
                Task.Run(() => _lockStore.ReleaseLockAsync(lockToken)).Wait();
            }
        }
コード例 #5
0
        /// <summary>
        /// If the id is already locked and the token is already in use, this method returns true
        /// </summary>
        /// <param name="id"></param>
        /// <param name="waitStartTime"></param>
        /// <param name="attemptTimeout"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        bool _tryLock(object id, float waitStartTime, float attemptTimeout, object token)
        {
            LockToken lockToken = new LockToken(token, TimeKeeper.MsSinceInitialization);

            while (TimeKeeper.MsSinceInitialization - waitStartTime < attemptTimeout)
            {
                if (_lockedIDs.ContainsKey(id) && _lockTokens.ContainsKey(token))
                {
                    return(true);
                }

                if (!_lockedIDs.TryAdd(id, TimeKeeper.MsSinceInitialization))
                {
                    Thread.Sleep(1);
                    continue;
                }


                lockToken.LastUpdateTime = TimeKeeper.MsSinceInitialization;
                if (!_lockTokens.ContainsKey(token) && !_lockTokens.TryAdd(token, lockToken))
                {
                    throw new CorruptStateException("Succesfully locked an Id, but could not add the LockToken. This shouldn't be possible, probable concurrency bug.");
                }

                return(true);
            }

            return(false);
        }
コード例 #6
0
        public void UT_LockToken_ToString_LockTokenHeaderWithBothBracketsReversed()
        {
            var lockToken = new LockToken("<(my-lock-token)>");
            var str       = lockToken.ToString(LockTokenFormat.LockTokenHeader);

            Assert.AreEqual("<my-lock-token>", str);
        }
コード例 #7
0
        public void UIT_WebDavClient_LockRefreshLockUnlock()
        {
            var client = CreateWebDavClientWithDebugHttpMessageHandler();

            // Lock.
            var lockInfo = new LockInfo();

            lockInfo.LockScope = LockScope.CreateExclusiveLockScope();
            lockInfo.LockType  = LockType.CreateWriteLockType();
            lockInfo.OwnerHref = "*****@*****.**";
            var       response            = client.LockAsync(this.webDavRootFolder, WebDavTimeoutHeaderValue.CreateWebDavTimeout(TimeSpan.FromSeconds(15)), WebDavDepthHeaderValue.Infinity, lockInfo).Result;
            var       lockResponseSuccess = response.IsSuccessStatusCode;
            LockToken lockToken           = WebDavHelper.GetLockTokenFromWebDavResponseMessage(response);

            // Refresh lock.
            response = client.RefreshLockAsync(this.webDavRootFolder, WebDavTimeoutHeaderValue.CreateWebDavTimeout(TimeSpan.FromSeconds(10)), lockToken).Result;
            var refreshLockResponseSuccess = response.IsSuccessStatusCode;

            // Unlock.
            response = client.UnlockAsync(this.webDavRootFolder, lockToken).Result;
            var unlockResponseSuccess = response.IsSuccessStatusCode;

            Assert.IsTrue(lockResponseSuccess);
            Assert.IsNotNull(lockToken);
            Assert.IsTrue(refreshLockResponseSuccess);
            Assert.IsTrue(unlockResponseSuccess);
        }
コード例 #8
0
ファイル: AzureLockStore.cs プロジェクト: csuffyy/BeeHive
        public async Task <bool> TryLockAsync(
            LockToken token,
            int tries = 16, // this is NOT retry - it is try
            int retryTimeoutMilliseconds = 15000,
            int timeoutMilliseconds      = 15000)
        {
            if (tries < 1)
            {
                tries = 1;
            }

            var blob = await GetBlobAsync(token.ResourceId);

            for (int i = 0; i < tries; i++)
            {
                try
                {
                    await blob.AcquireLeaseAsync(
                        TimeSpan.FromMilliseconds(timeoutMilliseconds),
                        token.TokenId.ToString("N"));

                    return(true);
                }
                catch (Exception e)
                {
                    TheTrace.TraceInformation("Lock attempt - already locked: {0}", e);
                    // ignore
                }
                await Task.Delay(TimeSpan.FromMilliseconds(retryTimeoutMilliseconds / tries));
            }

            return(false);
        }
コード例 #9
0
            void DisposeToken(LockToken token)
            {
                HandleToken();
                UpdateSocketState();
                token = null;

                void HandleToken()
                {
                    LockType tokenType = token.lockType;

                    switch (tokenType)
                    {
                    case LockType.Common:
                        Interlocked.Decrement(ref lockersCount);
                        break;

                    case LockType.Overall:
                        Interlocked.Decrement(ref overallLockersCount);
                        break;

                    default:
                        throw new Exception();     // TODO: исключение
                    }
                }
            }
コード例 #10
0
ファイル: WowManager.cs プロジェクト: github1-2-3/HBRelog
        public void Stop()
        {
            // try to aquire lock, if fail then kill process anyways.
            var lockAquried = Monitor.TryEnter(_lockObject, 500);

            if (IsRunning)
            {
                CloseGameProcess();
                if (Memory != null)
                {
                    Memory.Dispose();
                    Memory = null;
                }
                IsRunning = false;
                StartupSequenceIsComplete = false;
                if (LockToken != null)
                {
                    LockToken.Dispose();
                    LockToken = null;
                }
            }
            if (lockAquried)
            {
                Monitor.Exit(_lockObject);
            }

            Profile.Status = "Stopped";
        }
コード例 #11
0
        public async Task ICanLockForMoreThan30Seconds()
        {
            var locker = new AzureLockStore(
                new BlobSource()
            {
                ContainerName    = ContainerName,
                ConnectionString = ConnectionString,
                Path             = "this/is/great/"
            });

            var resource = Guid.NewGuid().ToString();
            var token    = new LockToken(resource);

            var canLock = await locker.TryLockAsync(token, 0, timeoutMilliseconds : 120 *1000);

            Assert.True(canLock);

            var newtoken = new LockToken(resource);

            Thread.Sleep(115 * 1000);
            var canDoubleLock = await locker.TryLockAsync(newtoken,
                                                          1, 100);

            await locker.ReleaseLockAsync(token);

            Assert.False(canDoubleLock);
        }
コード例 #12
0
        public void UT_LockToken_ToString_IfHeaderWithBothBrackets()
        {
            var lockToken = new LockToken("(<my-lock-token>)");
            var str       = lockToken.ToString(LockTokenFormat.IfHeader);

            Assert.AreEqual("(<my-lock-token>)", str);
        }
コード例 #13
0
        public void UIT_WebDavClient_LockAndPutWithToken()
        {
            var client = CreateWebDavClientWithDebugHttpMessageHandler();

            // Lock.
            var lockInfo = new LockInfo();

            lockInfo.LockScope = LockScope.CreateExclusiveLockScope();
            lockInfo.LockType  = LockType.CreateWriteLockType();
            lockInfo.OwnerHref = "*****@*****.**";
            var       response            = client.LockAsync(this.webDavRootFolder, WebDavTimeoutHeaderValue.CreateWebDavTimeout(TimeSpan.FromSeconds(15)), WebDavDepthHeaderValue.Infinity, lockInfo).Result;
            var       lockResponseSuccess = response.IsSuccessStatusCode;
            LockToken lockToken           = WebDavHelper.GetLockTokenFromWebDavResponseMessage(response);

            // Put file.
            var content    = new StreamContent(File.OpenRead(TestFile));
            var requestUrl = UriHelper.CombineUrl(this.webDavRootFolder, TestFile, true);

            response = client.PutAsync(requestUrl, content, lockToken).Result;
            var putResponseSuccess = response.IsSuccessStatusCode;

            // Delete file.
            response = client.DeleteAsync(requestUrl, lockToken).Result;
            var deleteResponseSuccess = response.IsSuccessStatusCode;

            // Unlock.
            response = client.UnlockAsync(this.webDavRootFolder, lockToken).Result;
            var unlockResponseSuccess = response.IsSuccessStatusCode;

            Assert.IsTrue(lockResponseSuccess);
            Assert.IsNotNull(lockToken);
            Assert.IsTrue(putResponseSuccess);
            Assert.IsTrue(deleteResponseSuccess);
            Assert.IsTrue(unlockResponseSuccess);
        }
コード例 #14
0
        public async Task UT_WebDavClient_LockRefreshLock()
        {
            var lockResponseContent = "<?xml version=\"1.0\" encoding=\"utf-8\"?><D:prop xmlns:D=\"DAV:\"><D:lockdiscovery><D:activelock><D:locktype><D:write/></D:locktype><D:lockscope><D:exclusive/></D:lockscope><D:depth>infinity</D:depth><D:owner><D:href>[email protected]</D:href></D:owner><D:timeout>Second-10</D:timeout><D:locktoken><D:href>opaquelocktoken:0af5a3d3-2ccd-42fb-b8c7-9c59c9b90944.22bc01d2b2e0e947</D:href></D:locktoken><D:lockroot><D:href>http://127.0.0.1/webdav/</D:href></D:lockroot></D:activelock></D:lockdiscovery></D:prop>";
            var oneMinuteTimeout    = WebDavTimeoutHeaderValue.CreateWebDavTimeout(TimeSpan.FromMinutes(1));
            var lockTokenString     = "(<opaquelocktoken:0af5a3d3-2ccd-42fb-b8c7-9c59c9b90944.22bc01d2b2e0e947>)";
            var parseResult         = NoTagList.TryParse(lockTokenString, out NoTagList noTagList);

            Assert.IsTrue(parseResult);
            var lockToken = new LockToken(noTagList.CodedUrl.AbsoluteUri);

            var mockHandler = new MockHttpMessageHandler();

            var requestHeaders = new List <KeyValuePair <string, string> >
            {
                new KeyValuePair <string, string>(WebDavRequestHeader.Timeout, oneMinuteTimeout.ToString()),
                new KeyValuePair <string, string>(WebDavRequestHeader.If, lockTokenString)
            };

            mockHandler.When(WebDavMethod.Lock, WebDavRootFolder).WithHeaders(requestHeaders).Respond(HttpStatusCode.OK, new StringContent(lockResponseContent));

            using (var client = CreateWebDavClient(mockHandler))
            {
                var response = await client.RefreshLockAsync(WebDavRootFolder, oneMinuteTimeout, lockToken);

                Assert.IsTrue(response.IsSuccessStatusCode);
            }
        }
コード例 #15
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldAcceptOnlyFirstRequestWithSameId()
        public virtual void ShouldAcceptOnlyFirstRequestWithSameId()
        {
            // given
            ReplicatedLockTokenStateMachine stateMachine = new ReplicatedLockTokenStateMachine(new InMemoryStateStorage <ReplicatedLockTokenState>(new ReplicatedLockTokenState()));
            int firstCandidateId = LockToken.nextCandidateId(stateMachine.CurrentToken().id());

            // when
            stateMachine.ApplyCommand(new ReplicatedLockTokenRequest(member(0), firstCandidateId), 1, r =>
            {
            });
            stateMachine.ApplyCommand(new ReplicatedLockTokenRequest(member(1), firstCandidateId), 2, r =>
            {
            });

            // then
            assertEquals(0, stateMachine.CurrentToken().id());
            assertEquals(member(0), stateMachine.CurrentToken().owner());

            // when
            stateMachine.ApplyCommand(new ReplicatedLockTokenRequest(member(1), firstCandidateId + 1), 3, r =>
            {
            });
            stateMachine.ApplyCommand(new ReplicatedLockTokenRequest(member(0), firstCandidateId + 1), 4, r =>
            {
            });

            // then
            assertEquals(1, stateMachine.CurrentToken().id());
            assertEquals(member(1), stateMachine.CurrentToken().owner());
        }
コード例 #16
0
ファイル: SyncLockTest.cs プロジェクト: mctraveler/MineSharp
 public void MonitorIsAcquired()
 {
     using (LockToken token = subject.Lock())
     {
         Monitor.Pulse(subject.Monitor);
     }
 }
コード例 #17
0
        public async Task IncrementAsync(string counterName, string id, long value)
        {
            var key    = string.Format("____COUNTER____{0}-{1}", counterName, id);
            var token  = new LockToken(key);
            var result = await _lockStore.TryLockAsync(token);

            if (!result)
            {
                throw new TimeoutException("Could not lock the resource");
            }
            var blob = await GetBlobAsync(key);

            var text = await blob.DownloadTextAsync();

            var current  = long.Parse(string.IsNullOrEmpty(text) ? "0" : text);
            var newValue = current + value;

            if (newValue < 0)
            {
                throw new InvalidOperationException("Value cannot get below zero: " + newValue);
            }

            await blob.UploadTextAsync(newValue.ToString());

            await _lockStore.ReleaseLockAsync(token);
        }
コード例 #18
0
        private bool EnterIfPossible(T lockingObject, byte lockType, LockRuleset rules, out LockToken <T> token, LockHolder h)
        {
            var entrancePair = rules.LockMatrix.EntrancePair(lockType, h.LockInfo); //найден (или не найден) допустимый переход из текущего состояния блокировок в требуемый тип

            if (entrancePair.HasValue)                                              //если найден
            {
                unchecked
                {
                    var blockExit = (int)entrancePair.Value.BlockExit;
                    Debug.Assert((entrancePair.Value.BlockEntrance & LockMatrix.SharenessCheckLock) == 0, "(entrancePair.Value.BlockEntrance & LockMatrix.SharenessCheckLock) == 0", "Не должно быть флага разделяемой блокировки в допустимом входном состоянии");
                    //делаем непосредственно переход
                    if (Interlocked.CompareExchange(ref h.LockInfo, blockExit, (int)entrancePair.Value.BlockEntrance) == (int)entrancePair.Value.BlockEntrance)
                    {
                        int sharedLockCount = 0;
                        //если взяли разделяемую блокировку с уже существующей
                        if ((blockExit & LockMatrix.SharenessCheckLock) == LockMatrix.SharenessCheckLock)
                        {
                            sharedLockCount = h.IncrLock(rules.LockMatrix.SelfSharedLockShift(lockType));//добавляем счётчик к количеству этих блокировок на заданном типе
                            Debug.Print($"sharedLockCount");
                            Debug.Assert(h.LockInfo == blockExit, "h.LockInfo == blockExit", "Состояние блокировок изменилось там, где не должно");
                            h.LockInfo = (int)((uint)h.LockInfo & LockMatrix.SharenessCheckLockDrop);//и сбрасываем этот флажок обратно. Никто не должен поменять LockInfo, т.к. с этим поднятым флажков не должно быть допустимых состояний.
                        }
                        token = new LockToken <T>(lockType, lockingObject, this, rules, sharedLockCount);
                        return(true);
                    }
                }
            }
            token = default(LockToken <T>);
            return(false);
        }
コード例 #19
0
        /// <summary>
        /// Selects a <see cref="LockToken" /> from the provided list, based on current
        /// availability of the associated resources, then mocks the critical section service
        /// by performing the action designated by <see cref="Behavior" />.
        /// </summary>
        /// <param name="tokens">The collection of tokens to choose from.</param>
        /// <param name="action">The action to execute; takes the acquired token as a parameter.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="tokens" /> is null.
        /// <para>or</para>
        /// <paramref name="action" /> is null.
        /// </exception>
        /// <exception cref="ArgumentException"><paramref name="tokens" /> contains no elements.</exception>
        /// <exception cref="AcquireLockTimeoutException">This instance is configured with <see cref="CriticalSectionMockBehavior.ThrowAcquireTimeoutException" />.</exception>
        /// <exception cref="HoldLockTimeoutException">This instance is configured with <see cref="CriticalSectionMockBehavior.ThrowHoldTimeoutException" />.</exception>
        public void Run(IEnumerable <LockToken> tokens, Action <LockToken> action)
        {
            if (tokens == null)
            {
                throw new ArgumentNullException(nameof(tokens));
            }

            if (!tokens.Any())
            {
                throw new ArgumentException("At least one token must be provided.", nameof(tokens));
            }

            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            switch (Behavior)
            {
            case CriticalSectionMockBehavior.ThrowAcquireTimeoutException:
                throw new AcquireLockTimeoutException("The lock could not be acquired within the designated time.");

            case CriticalSectionMockBehavior.ThrowHoldTimeoutException:
                throw new HoldLockTimeoutException("The specified action did not complete within the designated time.");
            }

            List <LockToken> tokenList     = tokens.ToList();
            LockToken        selectedToken = tokenList[_random.Next(tokenList.Count)];

            action(selectedToken);
        }
コード例 #20
0
        /// <summary>
        /// Selects a <see cref="LockToken" /> from the provided list, based on current
        /// availability of the associated resources, then obtains an exlusive lock
        /// and executes the specified <see cref="Action{LockToken}" /> before releasing the lock.
        /// </summary>
        /// <param name="tokens">The collection of tokens to choose from.</param>
        /// <param name="action">The action to execute; takes the acquired token as a parameter.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="tokens" /> is null.
        /// <para>or</para>
        /// <paramref name="action" /> is null.
        /// </exception>
        /// <exception cref="ArgumentException"><paramref name="tokens" /> contains no elements.</exception>
        /// <exception cref="AcquireLockTimeoutException">The lock could not be obtained within the acquisition timeout specified by the selected token.</exception>
        /// <exception cref="HoldLockTimeoutException"><paramref name="action" /> did not complete within the hold timeout specified by the selected token.</exception>
        public void Run(IEnumerable <LockToken> tokens, Action <LockToken> action)
        {
            if (tokens == null)
            {
                throw new ArgumentNullException(nameof(tokens));
            }

            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            if (!tokens.Any())
            {
                throw new ArgumentException("No lock tokens were specified.", nameof(tokens));
            }

            // Send the lock tokens in a random order to prevent picking the same one every time if they are all available
            Random random = new Random();
            IEnumerable <string> tokenIds   = tokens.Select(n => n.Key).OrderBy(n => random.Next());
            LockTicket           lockTicket = _lockManager.AcquireLock(tokenIds, tokens.First().AcquireTimeout, 1, _requestName);

            try
            {
                LockToken acquiredToken = tokens.First(n => n.Key == lockTicket.ResourceId);
                RunAction(acquiredToken, () => action(acquiredToken));
            }
            finally
            {
                _lockManager.ReleaseLock(lockTicket);
            }
        }
コード例 #21
0
        public bool TryAcqureLock(T lockingObject, LockRuleset rules, byte lockType, out LockToken <T> token)
        {
            var h = _locks.GetOrAdd(lockingObject, _ => new LockHolder(rules.LockMatrix.SelfSharedLocks));

            h.LastUsage = Stopwatch.GetTimestamp();

            return(EnterIfPossible(lockingObject, lockType, rules, out token, h));
        }
コード例 #22
0
        public async Task ReleaseLockAsync(LockToken token)
        {
            var blob = await GetBlobAsync(token.ResourceId);

            await blob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(token.TokenId.ToString("N")));

            token.RenewCancellation.Cancel();
        }
コード例 #23
0
        private static void RunAction(LockToken token, Action action)
        {
            bool finished = RunAction(action, token.HoldTimeout);

            if (!finished)
            {
                throw new HoldLockTimeoutException($"Action did not complete within {token.HoldTimeout}.");
            }
        }
コード例 #24
0
        private static void ReleaseLock(object key, LockToken @lock)
        {
            @lock.Release();

            if (@lock.IsNotUsed)
            {
                Locks.TryRemove(key, out var tmp);
            }
        }
コード例 #25
0
        /// <summary>
        /// This writes a message to the output stream
        /// </summary>
        /// <param name="physical">The phsyical connection to write to.</param>
        /// <param name="message">The message to be written.</param>
        internal ValueTask <WriteResult> WriteMessageTakingWriteLockAsync(PhysicalConnection physical, Message message)
        {
            Trace("Writing: " + message);
            message.SetEnqueued(physical); // this also records the read/write stats at this point

            bool      releaseLock = false;
            LockToken token       = default;

            try
            {
                // try to acquire it synchronously
                // note: timeout is specified in mutex-constructor
                var pending = _singleWriterMutex.TryWaitAsync(options: MutexSlim.WaitOptions.DisableAsyncContext);
                if (!pending.IsCompletedSuccessfully)
                {
                    return(WriteMessageTakingDelayedWriteLockAsync(pending, physical, message));
                }

                releaseLock = true;
                token       = pending.Result; // we can't use "using" for this, because we might not want to kill it yet
                if (!token.Success)           // (in particular, me might hand the lifetime to CompleteWriteAndReleaseLockAsync)
                {
                    message.Cancel();
                    Multiplexer?.OnMessageFaulted(message, null);
                    this.CompleteSyncOrAsync(message);
                    return(new ValueTask <WriteResult>(WriteResult.TimeoutBeforeWrite));
                }

                var result = WriteMessageInsideLock(physical, message);

                if (result == WriteResult.Success)
                {
                    var flush = physical.FlushAsync(false);
                    if (!flush.IsCompletedSuccessfully)
                    {
                        releaseLock = false; // so we don't release prematurely
                        return(CompleteWriteAndReleaseLockAsync(token, flush, message));
                    }

                    result = flush.Result; // we know it was completed, this is fine
                }

                UnmarkActiveMessage(message);
                physical.SetIdle();

                return(new ValueTask <WriteResult>(result));
            }
            catch (Exception ex) { return(new ValueTask <WriteResult>(HandleWriteException(message, ex))); }
            finally
            {
                if (releaseLock)
                {
                    token.Dispose();
                }
            }
        }
コード例 #26
0
        internal WriteResult WriteMessageTakingWriteLockSync(PhysicalConnection physical, Message message)
        {
            Trace("Writing: " + message);
            message.SetEnqueued(physical); // this also records the read/write stats at this point

            LockToken token = default;

            try
            {
                token = _singleWriterMutex.TryWait(WaitOptions.NoDelay);
                if (!token.Success)
                {
                    // we can't get it *instantaneously*; is there
                    // perhaps a backlog and active backlog processor?
                    bool haveBacklog;
                    lock (_backlog)
                    {
                        haveBacklog = _backlog.Count != 0;
                    }
                    if (haveBacklog)
                    {
                        PushToBacklog(message);
                        return(WriteResult.Success); // queued counts as success
                    }

                    // no backlog... try to wait with the timeout;
                    // if we *still* can't get it: that counts as
                    // an actual timeout
                    token = _singleWriterMutex.TryWait();
                    if (!token.Success)
                    {
                        message.Cancel();
                        Multiplexer?.OnMessageFaulted(message, null);
                        message.Complete();
                        return(WriteResult.TimeoutBeforeWrite);
                    }
                }

                var result = WriteMessageInsideLock(physical, message);

                if (result == WriteResult.Success)
                {
#pragma warning disable CS0618
                    result = physical.FlushSync(false, TimeoutMilliseconds);
#pragma warning restore CS0618
                }

                UnmarkActiveMessage(message);
                physical.SetIdle();
                return(result);
            }
            catch (Exception ex) { return(HandleWriteException(message, ex)); }
            finally { token.Dispose(); }
        }
コード例 #27
0
        public async Task CanNotRenewIfSomeoneElse()
        {
            var m     = new DynamoDBMutex(RegionEndpoint.EUWest1);
            var resId = Guid.NewGuid().ToString("N");
            var t     = await m.AcquireLockAsync(resId, TimeSpan.FromSeconds(10));

            var other = new LockToken(t.ResourceId, "other", t.LeaseExpiry);
            var t2    = await m.RenewAsync(other, TimeSpan.FromSeconds(20));

            Assert.Null(t2);
        }
コード例 #28
0
        public async Task <bool> TryLockAsync(
            LockToken token,
            int tries = 16, // this is NOT retry - it is try
            int retryTimeoutMilliseconds  = 15000,
            int timeoutMilliseconds       = 15000,
            int aquireTimeoutMilliseconds = 15000)
        {
            await EnsureExists();

            if (tries < 1)
            {
                tries = 1;
            }

            var blob = await GetBlobAsync(token.ResourceId);

            for (var i = 0; i < tries; i++)
            {
                try
                {
                    using (var cancellationTokenSource = new CancellationTokenSource(aquireTimeoutMilliseconds))
                    {
                        await blob.AcquireLeaseAsync(
                            TimeSpan.FromMilliseconds(Math.Min(MaxLockPossibleMilliseconds, timeoutMilliseconds)),
                            token.TokenId.ToString("N"), null, null, null, cancellationTokenSource.Token);
                    }

                    if (timeoutMilliseconds > MaxLockPossibleMilliseconds)
                    {
                        KeepExtendingLeaseAsync(async() =>
                        {
                            await blob.AcquireLeaseAsync(
                                TimeSpan.FromMilliseconds(MaxLockPossibleMilliseconds),
                                token.TokenId.ToString("N"));
                        }, TimeSpan.FromMilliseconds(MaxLockPossibleMilliseconds), token.RenewCancellation.Token, token.ResourceId);  // DO NOT WAIT THIS!!!
                    }

                    return(true);
                }
                catch (Exception e)
                {
                    TheTrace.TraceInformation("Lock attempt - already locked: {0}", e);
                    // ignore
                }

                if (i < tries - 1)
                {
                    await Task.Delay(TimeSpan.FromMilliseconds(retryTimeoutMilliseconds / tries));
                }
            }

            return(false);
        }
        public async Task UIT_WebDavClient_LockAndPutWithToken()
        {
            // This won't work on ownCloud/Nextcloud because they do not support WebDAV locking.
            // These unit integration test are skipped for ownCloud/Nextcloud.
            if (webDavRootFolder.Contains("nextcloud") || webDavRootFolder.Contains("owncloud"))
            {
                return;
            }

            using (var client = CreateWebDavClientWithDebugHttpMessageHandler())
            {
                // Lock.
                var lockInfo = new LockInfo()
                {
                    LockScope = LockScope.CreateExclusiveLockScope(),
                    LockType  = LockType.CreateWriteLockType(),
                    OwnerHref = "*****@*****.**"
                };

                var response = await client.LockAsync(webDavRootFolder, WebDavTimeoutHeaderValue.CreateWebDavTimeout(TimeSpan.FromSeconds(15)), WebDavDepthHeaderValue.Infinity, lockInfo);

                var       lockResponseSuccess = response.IsSuccessStatusCode;
                LockToken lockToken           = await WebDavHelper.GetLockTokenFromWebDavResponseMessage(response);

                var requestUrl = UriHelper.CombineUrl(webDavRootFolder, TestFile, true);

                // Put file.
                using (var fileStream = File.OpenRead(TestFile))
                {
                    var content = new StreamContent(fileStream);
                    response = await client.PutAsync(requestUrl, content, lockToken);
                }

                var putResponseSuccess = response.IsSuccessStatusCode;

                // Delete file.
                response = await client.DeleteAsync(requestUrl, lockToken);

                var deleteResponseSuccess = response.IsSuccessStatusCode;

                // Unlock.
                response = await client.UnlockAsync(webDavRootFolder, lockToken);

                var unlockResponseSuccess = response.IsSuccessStatusCode;

                Assert.IsTrue(lockResponseSuccess);
                Assert.IsNotNull(lockToken);
                Assert.IsTrue(putResponseSuccess);
                Assert.IsTrue(deleteResponseSuccess);
                Assert.IsTrue(unlockResponseSuccess);
            }
        }
コード例 #30
0
 public void Dispose()
 {
     lock (_bigLock)
     {
         LockToken miniLock = _lockMap[_itemId];
         miniLock.Count--;
         if (miniLock.Count == 0)
         {
             _lockMap.Remove(_itemId);
         }
         Monitor.Exit(miniLock);
     }
 }