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));
            }
예제 #2
0
            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));
            }
예제 #3
0
            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);
                }
            }
예제 #5
0
            public void CanAquireLockIfNoLockAquired()
            {
                using (var aggregateLock = new AggregateLock(typeof(Aggregate), GuidStrategy.NewGuid()))
                {
                    aggregateLock.Aquire();

                    Assert.True(aggregateLock.Aquired);
                }
            }
예제 #6
0
            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);
                }
            }
예제 #8
0
            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 void CanReleaseLockIfLockAquired()
            {
                using (var aggregateLock = new AggregateLock(typeof(Aggregate), GuidStrategy.NewGuid()))
                {
                    aggregateLock.Aquire();
                    aggregateLock.Release();

                    Assert.False(aggregateLock.Aquired);
                }
            }
예제 #12
0
        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));
        }