Exemplo n.º 1
0
        public void HandlerTests(string message, object initialState)
        {
            using var context = new LockState(new Key("", "", TimeSpan.FromSeconds(1)), "key", CancellationToken.None);
            switch (initialState)
            {
            case State.WithKey:
                context.SetWithKey();
                break;

            case State.Done:
                context.SetDone();
                break;
            }

            context.Handler(new StackExchange.Redis.RedisChannel(), message);

            switch (initialState)
            {
            case State.WaitingForKey:
                if (context.Identifier == message)
                {
                    Assert.Equal(State.WithKey, context.State);
                }
                break;

            case State.WithKey:
                if (context.Identifier == message)
                {
                    Assert.Equal(State.WithKey, context.State);
                }
                else
                {
                    Assert.Equal(State.Done, context.State);
                }
                break;

            case State.Done:
                Assert.Equal(State.Done, context.State);
                break;
            }
        }
Exemplo n.º 2
0
        public async Task <T> LockAsync <T>(Key key, Func <CancellationToken, Task <T> > callback, CancellationToken cancellationToken)
        {
            if (callback == null)
            {
                throw new ArgumentNullException(nameof(callback));
            }

            using var state = new LockState(key, _identifierGenerator.GetUniqueKey(15), cancellationToken);
            try
            {
                await _scriptLibrary.SubscribeAsync(state).ConfigureAwait(false);

                try
                {
                    if (await _scriptLibrary.GetLockOrAddToQueue(state.Parameters).ConfigureAwait(false))
                    {
                        state.SetWithKey();
                    }

                    //we start protecting after the first manipulation in redis, to properly hit the expiration if needed
                    using (var protector = new LockProtector(_scriptLibrary, state))
                    {
                        await state.WaitingTask.ConfigureAwait(false);

                        if (state.Token.IsCancellationRequested)
                        {
                            throw new TaskCanceledException();
                        }
                        return(await callback(state.Token).ConfigureAwait(false));
                    }
                }
                finally
                {
                    await _scriptLibrary.FreeLockAndPop(state.Parameters).ConfigureAwait(false);
                }
            }
            finally
            {
                await _scriptLibrary.UnSubscribeAsync(state).ConfigureAwait(false);
            }
        }
Exemplo n.º 3
0
        public async Task CheckSituationIsCorrectlyInterpreted(int value, object state)
        {
            var library = new Mock <IScriptLibrary>();

            using var context = new LockState(new Key("", "", TimeSpan.FromMilliseconds(100)), "id4", CancellationToken.None);
            switch (state)
            {
            case State.WithKey:
                context.SetWithKey();
                break;

            case State.Done:
                context.SetDone();
                break;
            }
            using var protector = new LockProtector(library.Object, context, false);
            library.Setup(l => l.GetLockOrAddToQueue(It.IsAny <LockLuaParameters>())).ReturnsAsync(() => true);
            library.Setup(l => l.GetKeySituation(It.IsAny <LockLuaParameters>())).ReturnsAsync(() => value);

            await protector.EnsureNoDeadLockAsync();

            switch (value)
            {
            case 2:
                switch (context.State)
                {
                case State.WaitingForKey:
                    Assert.Equal(State.WithKey, context.State);
                    break;

                case State.WithKey:
                case State.Done:
                    Assert.Equal(State.Done, context.State);
                    break;
                }
                break;
            }
        }