public void AquireWillBlockIfAnotherLockAlreadyAquiredOnSameAggregate() { var correlationId = GuidStrategy.NewGuid(); var firstLockAquired = new ManualResetEvent(initialState: false); var secondLockAquired = new ManualResetEvent(initialState: false); var blockedTime = TimeSpan.Zero; Task.Factory.StartNew(() => { firstLockAquired.WaitOne(); using (var aggregateLock = new AggregateLock(typeof(Aggregate), correlationId)) { var timer = Stopwatch.StartNew(); aggregateLock.Aquire(); timer.Stop(); blockedTime = timer.Elapsed; secondLockAquired.Set(); } }); using (var aggregateLock = new AggregateLock(typeof(Aggregate), correlationId)) { aggregateLock.Aquire(); firstLockAquired.Set(); Thread.Sleep(100); } secondLockAquired.WaitOne(); Assert.InRange(blockedTime, TimeSpan.FromMilliseconds(50), TimeSpan.FromMilliseconds(150)); }
public void AquireWillNotBlockIfAnotherLockAlreadyAquiredOnAnotherAggregate() { var firstLockAquired = new ManualResetEvent(initialState: false); var secondLockAquired = new ManualResetEvent(initialState: false); var blockedTime = TimeSpan.Zero; Task.Factory.StartNew(() => { firstLockAquired.WaitOne(); using (var aggregateLock = new AggregateLock(typeof(Aggregate), GuidStrategy.NewGuid())) { var timer = Stopwatch.StartNew(); aggregateLock.Aquire(); timer.Stop(); blockedTime = timer.Elapsed; secondLockAquired.Set(); } }); using (var aggregateLock = new AggregateLock(typeof(Aggregate), GuidStrategy.NewGuid())) { aggregateLock.Aquire(); firstLockAquired.Set(); Thread.Sleep(100); } secondLockAquired.WaitOne(); Assert.InRange(blockedTime, TimeSpan.FromMilliseconds(0), TimeSpan.FromMilliseconds(50)); }
public void CanDisposeIfLockAquired() { var aggregateLock = new AggregateLock(typeof(Aggregate), GuidStrategy.NewGuid()); aggregateLock.Aquire(); aggregateLock.Dispose(); }
public void CanAquireLockIfNoLockAquired() { using (var aggregateLock = new AggregateLock(typeof(Aggregate), GuidStrategy.NewGuid())) { aggregateLock.Aquire(); Assert.True(aggregateLock.Aquired); } }
public void CanReleaseLockIfLockAquired() { using (var aggregateLock = new AggregateLock(typeof(Aggregate), GuidStrategy.NewGuid())) { aggregateLock.Aquire(); aggregateLock.Release(); Assert.False(aggregateLock.Aquired); } }
public void CannotAquireLockIfLockAlreadyAquired() { var aggregateId = GuidStrategy.NewGuid(); using (var aggregateLock = new AggregateLock(typeof(Aggregate), aggregateId)) { aggregateLock.Aquire(); var ex = Assert.Throws<InvalidOperationException>(() => aggregateLock.Aquire()); Assert.Equal(Exceptions.AggregateLockAlreadyHeld.FormatWith(typeof(Aggregate), aggregateId), ex.Message); } }
public void CannotReleaseLockIfLockNotAquired() { var aggregateId = GuidStrategy.NewGuid(); using (var aggregateLock = new AggregateLock(typeof(Aggregate), aggregateId)) { var ex = Assert.Throws <InvalidOperationException>(() => aggregateLock.Release()); Assert.Equal(Exceptions.AggregateLockNotHeld.FormatWith(typeof(Aggregate), aggregateId), ex.Message); } }
public void CanDisposeMoreThanOnce() { var aggregateLock = new AggregateLock(typeof(Aggregate), GuidStrategy.NewGuid()); aggregateLock.Aquire(); aggregateLock.Dispose(); aggregateLock.Dispose(); }
public void CanDisposeIfLockNotAquired() { var aggregateLock = new AggregateLock(typeof(Aggregate), GuidStrategy.NewGuid()); aggregateLock.Dispose(); }
public override async Task <UpdateExistingAccountCommand> HandleAsync(UpdateExistingAccountCommand command, CancellationToken cancellationToken = new CancellationToken()) { Guid eventId; using (var uow = new AccountContext(_options)) { using (var trans = uow.Database.BeginTransaction()) { var accountRepositoryAsync = new AccountRepositoryAsync(new EFUnitOfWork(uow)); AggregateLock aggregateLock = null; try { aggregateLock = await accountRepositoryAsync.LockAsync(command.AccountId.ToString(), command.LockBy, cancellationToken); var account = await accountRepositoryAsync.GetAsync(command.AccountId); account.Name = new Name(account, command.Name.FirstName, command.Name.LastName); account.ContactDetails = new ContactDetails(account, command.ContactDetails.Email, command.ContactDetails.TelephoneNumber); account.CardDetails = new CardDetails(account, command.CardDetails.CardNumber, command.CardDetails.CardSecurityCode); account.Addresses = command.Addresses; await accountRepositoryAsync.UpdateAsync(account, aggregateLock, cancellationToken); eventId = await _commandProcessor.DepositPostAsync(new AccountEvent { Id = Guid.NewGuid(), AccountId = account.AccountId.ToString(), Addresses = account.Addresses.Select( addr => new AddressEvent { AddressType = addr.AddressType.ToString(), FistLineOfAddress = addr.FistLineOfAddress, State = addr.State, ZipCode = addr.ZipCode }).ToList(), Name = new NameEvent { FirstName = account.Name.FirstName, LastName = account.Name.LastName }, CardDetails = new CardDetailsEvent { CardNumber = account.CardDetails.CardNumber, CardSecurityCode = account.CardDetails.CardSecurityCode }, ContactDetails = new ContactDetailsEvent { Email = account.ContactDetails.Email, TelephoneNumber = account.ContactDetails.TelephoneNumber } }, false, cancellationToken); trans.Commit(); } finally { if (aggregateLock != null) { await aggregateLock.ReleaseAsync(cancellationToken); } } } } await _commandProcessor.ClearOutboxAsync(new [] { eventId }); return(await base.HandleAsync(command, cancellationToken)); }