public void EnsureDisposeWorks() { var library = new Mock <IScriptLibrary>(); using var context = new LockState(new Key("", "", TimeSpan.FromSeconds(1)), "id", CancellationToken.None); using (var protector = new LockProtector(library.Object, context)) { } Assert.Equal(State.Done, context.State); }
public async Task EnsureNoDeadLockAsyncShouldStop2() { var library = new Mock <IScriptLibrary>(); using var context = new LockState(new Key("", "", TimeSpan.FromSeconds(1)), "id3", CancellationToken.None); using var protector = new LockProtector(library.Object, context, false); context.SetDone(new Exception("")); await protector.EnsureNoDeadLockAsync(); Assert.True(true); }
public async Task CheckSituationIsCorrectlyInterpretedFailCase2() { var library = new Mock <IScriptLibrary>(); using var context = new LockState(new Key("", "", TimeSpan.FromSeconds(1)), "id6", CancellationToken.None); using var protector = new LockProtector(library.Object, context, false); library.Setup(l => l.GetKeySituation(It.IsAny <LockLuaParameters>())).ReturnsAsync(() => 4); await protector.EnsureNoDeadLockAsync(); Assert.NotNull(context.WaitingTask.Exception?.InnerException); Assert.IsType <NotImplementedException>(context.WaitingTask.Exception?.InnerException); }
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); } }
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; } }