public async Task Save_fails_when_data_changes_between_read_and_update_on_same_thread()
        {
            var sagaId = Guid.NewGuid();
            var saga = new TestSagaData
            {
                Id = sagaId,
                SomeId = sagaId.ToString()
            };
            var persister = new InMemorySagaPersister();
            var insertSession = new InMemorySynchronizedStorageSession();
            await persister.Save(saga, SagaMetadataHelper.GetMetadata<TestSaga>(saga), insertSession, new ContextBag());
            await insertSession.CompleteAsync();

            var winningContext = new ContextBag();
            var record = await persister.Get<TestSagaData>(saga.Id, new InMemorySynchronizedStorageSession(), winningContext);
            var losingContext = new ContextBag();
            var staleRecord = await persister.Get<TestSagaData>("SomeId", sagaId.ToString(), new InMemorySynchronizedStorageSession(), losingContext);

            var winningSaveSession = new InMemorySynchronizedStorageSession();
            var losingSaveSession = new InMemorySynchronizedStorageSession();

            await persister.Update(record, winningSaveSession, winningContext);
            await persister.Update(staleRecord, losingSaveSession, losingContext);

            await winningSaveSession.CompleteAsync();

            Assert.That(async () => await losingSaveSession.CompleteAsync(), Throws.InstanceOf<Exception>().And.Message.StartsWith($"InMemorySagaPersister concurrency violation: saga entity Id[{saga.Id}] already saved."));
        }
예제 #2
0
        public async Task Save_fails_when_writing_same_data_twice()
        {
            var saga = new TestSagaData
            {
                Id = Guid.NewGuid()
            };
            var persister     = new InMemorySagaPersister();
            var insertSession = new InMemorySynchronizedStorageSession();
            await persister.Save(saga, SagaMetadataHelper.GetMetadata <TestSaga>(saga), insertSession, new ContextBag());

            await insertSession.CompleteAsync();

            var retrievingContext = new ContextBag();
            var returnedSaga1     = await persister.Get <TestSagaData>(saga.Id, new InMemorySynchronizedStorageSession(), retrievingContext);

            var winningSaveSession = new InMemorySynchronizedStorageSession();
            var losingSaveSession  = new InMemorySynchronizedStorageSession();

            await persister.Update(returnedSaga1, winningSaveSession, retrievingContext);

            await persister.Update(returnedSaga1, losingSaveSession, retrievingContext);

            await winningSaveSession.CompleteAsync();

            Assert.That(async() => await losingSaveSession.CompleteAsync(), Throws.InstanceOf <Exception>().And.Message.StartsWith($"InMemorySagaPersister concurrency violation: saga entity Id[{saga.Id}] already saved."));
        }
예제 #3
0
        public async Task Save_fails_when_data_changes_between_read_and_update_on_same_thread()
        {
            var sagaId = Guid.NewGuid();
            var saga   = new TestSagaData
            {
                Id     = sagaId,
                SomeId = sagaId.ToString()
            };
            var persister     = new InMemorySagaPersister();
            var insertSession = new InMemorySynchronizedStorageSession();
            await persister.Save(saga, SagaMetadataHelper.GetMetadata <TestSaga>(saga), insertSession, new ContextBag());

            await insertSession.CompleteAsync();

            var winningContext = new ContextBag();
            var record         = await persister.Get <TestSagaData>(saga.Id, new InMemorySynchronizedStorageSession(), winningContext);

            var losingContext = new ContextBag();
            var staleRecord   = await persister.Get <TestSagaData>("SomeId", sagaId.ToString(), new InMemorySynchronizedStorageSession(), losingContext);

            var winningSaveSession = new InMemorySynchronizedStorageSession();
            var losingSaveSession  = new InMemorySynchronizedStorageSession();

            await persister.Update(record, winningSaveSession, winningContext);

            await persister.Update(staleRecord, losingSaveSession, losingContext);

            await winningSaveSession.CompleteAsync();

            Assert.That(async() => await losingSaveSession.CompleteAsync(), Throws.InstanceOf <Exception>().And.Message.StartsWith($"InMemorySagaPersister concurrency violation: saga entity Id[{saga.Id}] already saved."));
        }
예제 #4
0
        public async Task Save_process_is_repeatable()
        {
            var sagaId = Guid.NewGuid();
            var saga   = new TestSagaData
            {
                Id     = sagaId,
                SomeId = sagaId.ToString()
            };
            var persister     = new InMemorySagaPersister();
            var insertSession = new InMemorySynchronizedStorageSession();
            await persister.Save(saga, SagaMetadataHelper.GetMetadata <TestSaga>(saga), insertSession, new ContextBag());

            await insertSession.CompleteAsync();

            var winningSessionContext = new ContextBag();
            var returnedSaga1         = await Task.Run(() => persister.Get <TestSagaData>(saga.Id, new InMemorySynchronizedStorageSession(), winningSessionContext));

            var losingSessionContext = new ContextBag();
            var returnedSaga2        = await persister.Get <TestSagaData>("SomeId", sagaId.ToString(), new InMemorySynchronizedStorageSession(), losingSessionContext);

            var winningSaveSession = new InMemorySynchronizedStorageSession();
            var losingSaveSession  = new InMemorySynchronizedStorageSession();

            await persister.Update(returnedSaga1, winningSaveSession, winningSessionContext);

            await persister.Update(returnedSaga2, losingSaveSession, losingSessionContext);

            await winningSaveSession.CompleteAsync();

            Assert.That(async() => await losingSaveSession.CompleteAsync(), Throws.InstanceOf <Exception>().And.Message.StartsWith($"InMemorySagaPersister concurrency violation: saga entity Id[{saga.Id}] already saved."));

            losingSessionContext = new ContextBag();
            var returnedSaga3 = await Task.Run(() => persister.Get <TestSagaData>("SomeId", sagaId.ToString(), new InMemorySynchronizedStorageSession(), losingSessionContext));

            winningSessionContext = new ContextBag();
            var returnedSaga4 = await persister.Get <TestSagaData>(saga.Id, new InMemorySynchronizedStorageSession(), winningSessionContext);

            winningSaveSession = new InMemorySynchronizedStorageSession();
            losingSaveSession  = new InMemorySynchronizedStorageSession();

            await persister.Update(returnedSaga4, winningSaveSession, winningSessionContext);

            await persister.Update(returnedSaga3, losingSaveSession, losingSessionContext);

            await winningSaveSession.CompleteAsync();

            Assert.That(async() => await losingSaveSession.CompleteAsync(), Throws.InstanceOf <Exception>().And.Message.StartsWith($"InMemorySagaPersister concurrency violation: saga entity Id[{saga.Id}] already saved."));
        }
        public async Task It_should_successfully_update_the_saga()
        {
            var id       = Guid.NewGuid();
            var sagaData = new SagaWithoutUniquePropertyData
            {
                Id = id,
                NonUniqueString = "whatever"
            };

            var persister = new InMemorySagaPersister();

            // first session
            var session = new InMemorySynchronizedStorageSession();

            await persister.Save(sagaData, SagaCorrelationProperty.None, session, new ContextBag());

            await session.CompleteAsync();

            // second session
            var session2 = new InMemorySynchronizedStorageSession();

            var ctx  = new ContextBag();
            var saga = await persister.Get <SagaWithoutUniquePropertyData>(id, session2, ctx);

            saga.NonUniqueString = "asdfasdf";

            await persister.Update(saga, session2, ctx);

            await session2.CompleteAsync();

            var result = await persister.Get <SagaWithoutUniquePropertyData>(sagaData.Id, new InMemorySynchronizedStorageSession(), new ContextBag());

            Assert.That(result, Is.Not.Null);
            Assert.That(result.NonUniqueString, Is.EqualTo("asdfasdf"));
        }
        public async Task It_should_successfully_update_the_saga()
        {
            var id = Guid.NewGuid();
            var sagaData = new SagaWithoutUniquePropertyData
            {
                Id = id,
                NonUniqueString = "whatever"
            };

            var persister = new InMemorySagaPersister();

            // first session
            var session = new InMemorySynchronizedStorageSession();

            await persister.Save(sagaData, SagaCorrelationProperty.None, session, new ContextBag());

            await session.CompleteAsync();

            // second session
            var session2 = new InMemorySynchronizedStorageSession();

            var ctx = new ContextBag();
            var saga = await persister.Get<SagaWithoutUniquePropertyData>(id, session2, ctx);
            saga.NonUniqueString = "asdfasdf";

            await persister.Update(saga, session2, ctx);

            await session2.CompleteAsync();

            var result = await persister.Get<SagaWithoutUniquePropertyData>(sagaData.Id, new InMemorySynchronizedStorageSession(), new ContextBag());

            Assert.That(result, Is.Not.Null);
            Assert.That(result.NonUniqueString, Is.EqualTo("asdfasdf"));
        }
예제 #7
0
        public async Task It_should_persist_successfully()
        {
            var saga1 = new SagaWithUniquePropertyData
            {
                Id           = Guid.NewGuid(),
                UniqueString = "whatever"
            };
            var saga2 = new SagaWithUniquePropertyData
            {
                Id           = Guid.NewGuid(),
                UniqueString = "whatever"
            };

            var persister = new InMemorySagaPersister();

            var firstInsertSession = new InMemorySynchronizedStorageSession();
            await persister.Save(saga1, SagaMetadataHelper.GetMetadata <SagaWithUniqueProperty>(saga1), firstInsertSession, new ContextBag());

            await firstInsertSession.CompleteAsync();

            var updateSession = new InMemorySynchronizedStorageSession();

            saga1 = await persister.Get <SagaWithUniquePropertyData>(saga1.Id, updateSession, new ContextBag());

            saga1.UniqueString = "whatever2";
            await persister.Update(saga1, updateSession, new ContextBag());

            await updateSession.CompleteAsync();

            var secondInsertSession = new InMemorySynchronizedStorageSession();
            await persister.Save(saga2, SagaMetadataHelper.GetMetadata <SagaWithUniqueProperty>(saga2), secondInsertSession, new ContextBag());

            await secondInsertSession.CompleteAsync();
        }
        public void It_should_persist_successfully()
        {
            var saga1 = new SagaWithUniqueProperty { Id = Guid.NewGuid(), UniqueString = "whatever"};

            var inMemorySagaPersister = new InMemorySagaPersister() as ISagaPersister;
            inMemorySagaPersister.Save(saga1);
            saga1 = inMemorySagaPersister.Get<SagaWithUniqueProperty>(saga1.Id);
            inMemorySagaPersister.Update(saga1);
        }
예제 #9
0
        public async Task Save_fails_when_data_changes_between_concurrent_instances()
        {
            var saga = new TestSagaData
            {
                Id = Guid.NewGuid()
            };

            var persister      = new InMemorySagaPersister();
            var storageAdapter = new InMemoryTransactionalSynchronizedStorageAdapter();
            var insertSession  = new InMemorySynchronizedStorageSession();

            await persister.Save(saga, SagaMetadataHelper.GetMetadata <TestSaga>(saga), insertSession, new ContextBag());

            await insertSession.CompleteAsync();

            Assert.That(async() =>
            {
                using (var tx = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    Transaction.Current.EnlistDurable(EnlistmentWhichEnforcesDtcEscalation.Id, new EnlistmentWhichEnforcesDtcEscalation(), EnlistmentOptions.None);

                    var transportTransaction = new TransportTransaction();
                    transportTransaction.Set(Transaction.Current);

                    var unenlistedSession = new InMemorySynchronizedStorageSession();

                    var enlistedSession = await storageAdapter.TryAdapt(transportTransaction, new ContextBag());

                    var unenlistedSessionContext = new ContextBag();
                    var unenlistedRecord         = await persister.Get <TestSagaData>(saga.Id, unenlistedSession, unenlistedSessionContext);
                    var enlistedSessionContext   = new ContextBag();
                    var enlistedRecord           = await persister.Get <TestSagaData>("Id", saga.Id, enlistedSession, enlistedSessionContext);

                    await persister.Update(unenlistedRecord, unenlistedSession, unenlistedSessionContext);
                    await persister.Update(enlistedRecord, enlistedSession, enlistedSessionContext);

                    await unenlistedSession.CompleteAsync();

                    tx.Complete();
                }
            }, Throws.Exception.TypeOf <TransactionAbortedException>());
        }
        public async Task Save_fails_when_data_changes_between_concurrent_instances()
        {
            var saga = new TestSagaData
            {
                Id = Guid.NewGuid()
            };

            var persister = new InMemorySagaPersister();
            var storageAdapter = new InMemoryTransactionalSynchronizedStorageAdapter();
            var insertSession = new InMemorySynchronizedStorageSession();

            await persister.Save(saga, SagaMetadataHelper.GetMetadata<TestSaga>(saga), insertSession, new ContextBag());
            await insertSession.CompleteAsync();

            Assert.That(async () =>
            {
                using (var tx = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    Transaction.Current.EnlistDurable(EnlistmentWhichEnforcesDtcEscalation.Id, new EnlistmentWhichEnforcesDtcEscalation(), EnlistmentOptions.None);

                    var transportTransaction = new TransportTransaction();
                    transportTransaction.Set(Transaction.Current);

                    var unenlistedSession = new InMemorySynchronizedStorageSession();

                    var enlistedSession = await storageAdapter.TryAdapt(transportTransaction, new ContextBag());

                    var unenlistedSessionContext = new ContextBag();
                    var unenlistedRecord = await persister.Get<TestSagaData>(saga.Id, unenlistedSession, unenlistedSessionContext);
                    var enlistedSessionContext = new ContextBag();
                    var enlistedRecord = await persister.Get<TestSagaData>("Id", saga.Id, enlistedSession, enlistedSessionContext);

                    await persister.Update(unenlistedRecord, unenlistedSession, unenlistedSessionContext);
                    await persister.Update(enlistedRecord, enlistedSession, enlistedSessionContext);

                    await unenlistedSession.CompleteAsync();

                    tx.Complete();
                }
            }, Throws.Exception.TypeOf<TransactionAbortedException>());
        }
        public void It_should_persist_successfully()
        {
            var saga1 = new SagaWithUniqueProperty {
                Id = Guid.NewGuid(), UniqueString = "whatever"
            };

            var inMemorySagaPersister = new InMemorySagaPersister() as ISagaPersister;

            inMemorySagaPersister.Save(saga1);
            saga1 = inMemorySagaPersister.Get <SagaWithUniqueProperty>(saga1.Id);
            inMemorySagaPersister.Update(saga1);
        }
        public void It_should_persist_successfully()
        {
            var saga1 = new SagaWithUniqueProperty {Id = Guid.NewGuid(), UniqueString = "whatever1"};
            var saga2 = new SagaWithUniqueProperty {Id = Guid.NewGuid(), UniqueString = "whatever"};
            var inMemorySagaPersister = new InMemorySagaPersister() as ISagaPersister;

            inMemorySagaPersister.Save(saga1);
            inMemorySagaPersister.Save(saga2);

            Assert.Throws<InvalidOperationException>(() =>
            {
                var saga = inMemorySagaPersister.Get<SagaWithUniqueProperty>(saga2.Id);
                saga.UniqueString = "whatever1";
                inMemorySagaPersister.Update(saga);
            });
        }
        public void It_should_persist_successfully_for_two_unique_properties()
        {
            var saga1 = new SagaWithTwoUniqueProperties { Id = Guid.NewGuid(), UniqueString = "whatever1", UniqueInt = 5};
            var saga2 = new SagaWithTwoUniqueProperties { Id = Guid.NewGuid(), UniqueString = "whatever", UniqueInt = 37};
            var inMemorySagaPersister = new InMemorySagaPersister() as ISagaPersister;

            inMemorySagaPersister.Save(saga1);
            inMemorySagaPersister.Save(saga2);

            Assert.Throws<InvalidOperationException>(() =>
            {
                var saga = inMemorySagaPersister.Get<SagaWithTwoUniqueProperties>(saga2.Id);
                saga.UniqueInt = 5;
                inMemorySagaPersister.Update(saga);
            });
        }
        public void It_should_persist_successfully_for_two_unique_properties()
        {
            var saga1 = new SagaWithTwoUniqueProperties {
                Id = Guid.NewGuid(), UniqueString = "whatever1", UniqueInt = 5
            };
            var saga2 = new SagaWithTwoUniqueProperties {
                Id = Guid.NewGuid(), UniqueString = "whatever", UniqueInt = 37
            };
            var inMemorySagaPersister = new InMemorySagaPersister() as ISagaPersister;

            inMemorySagaPersister.Save(saga1);
            inMemorySagaPersister.Save(saga2);

            Assert.Throws <InvalidOperationException>(() =>
            {
                var saga       = inMemorySagaPersister.Get <SagaWithTwoUniqueProperties>(saga2.Id);
                saga.UniqueInt = 5;
                inMemorySagaPersister.Update(saga);
            });
        }
        public async Task It_should_persist_successfully()
        {
            var saga1 = new SagaWithUniquePropertyData
            {
                Id = Guid.NewGuid(),
                UniqueString = "whatever"
            };
            var persister = new InMemorySagaPersister();

            var insertSession = new InMemorySynchronizedStorageSession();
            await persister.Save(saga1, SagaMetadataHelper.GetMetadata<SagaWithUniqueProperty>(saga1), insertSession, new ContextBag());
            await insertSession.CompleteAsync();

            var updatingContext = new ContextBag();
            saga1 = await persister.Get<SagaWithUniquePropertyData>(saga1.Id, new InMemorySynchronizedStorageSession(), updatingContext);

            var updateSession = new InMemorySynchronizedStorageSession();
            await persister.Update(saga1, updateSession, updatingContext);
            await updateSession.CompleteAsync();
        }
        public void It_should_persist_successfully()
        {
            var saga1 = new SagaWithUniqueProperty {
                Id = Guid.NewGuid(), UniqueString = "whatever1"
            };
            var saga2 = new SagaWithUniqueProperty {
                Id = Guid.NewGuid(), UniqueString = "whatever"
            };
            var inMemorySagaPersister = new InMemorySagaPersister() as ISagaPersister;

            inMemorySagaPersister.Save(saga1);
            inMemorySagaPersister.Save(saga2);

            Assert.Throws <InvalidOperationException>(() =>
            {
                var saga          = inMemorySagaPersister.Get <SagaWithUniqueProperty>(saga2.Id);
                saga.UniqueString = "whatever1";
                inMemorySagaPersister.Update(saga);
            });
        }
        public async Task Save_process_is_repeatable()
        {
            var sagaId = Guid.NewGuid();
            var saga = new TestSagaData
            {
                Id = sagaId,
                SomeId = sagaId.ToString()
            };
            var persister = new InMemorySagaPersister();
            var insertSession = new InMemorySynchronizedStorageSession();
            await persister.Save(saga, SagaMetadataHelper.GetMetadata<TestSaga>(saga), insertSession, new ContextBag());
            await insertSession.CompleteAsync();

            var winningSessionContext = new ContextBag();
            var returnedSaga1 = await Task.Run(() => persister.Get<TestSagaData>(saga.Id, new InMemorySynchronizedStorageSession(), winningSessionContext));

            var losingSessionContext = new ContextBag();
            var returnedSaga2 = await persister.Get<TestSagaData>("SomeId", sagaId.ToString(), new InMemorySynchronizedStorageSession(), losingSessionContext);

            var winningSaveSession = new InMemorySynchronizedStorageSession();
            var losingSaveSession = new InMemorySynchronizedStorageSession();

            await persister.Update(returnedSaga1, winningSaveSession, winningSessionContext);
            await persister.Update(returnedSaga2, losingSaveSession, losingSessionContext);

            await winningSaveSession.CompleteAsync();
            Assert.That(async () => await losingSaveSession.CompleteAsync(), Throws.InstanceOf<Exception>().And.Message.StartsWith($"InMemorySagaPersister concurrency violation: saga entity Id[{saga.Id}] already saved."));

            losingSessionContext = new ContextBag();
            var returnedSaga3 = await Task.Run(() => persister.Get<TestSagaData>("SomeId", sagaId.ToString(), new InMemorySynchronizedStorageSession(), losingSessionContext));

            winningSessionContext = new ContextBag();
            var returnedSaga4 = await persister.Get<TestSagaData>(saga.Id, new InMemorySynchronizedStorageSession(), winningSessionContext);

            winningSaveSession = new InMemorySynchronizedStorageSession();
            losingSaveSession = new InMemorySynchronizedStorageSession();

            await persister.Update(returnedSaga4, winningSaveSession, winningSessionContext);
            await persister.Update(returnedSaga3, losingSaveSession, losingSessionContext);

            await winningSaveSession.CompleteAsync();

            Assert.That(async () => await losingSaveSession.CompleteAsync(), Throws.InstanceOf<Exception>().And.Message.StartsWith($"InMemorySagaPersister concurrency violation: saga entity Id[{saga.Id}] already saved."));
        }
예제 #18
0
 public void Update(ISagaData sagaData, string[] sagaDataPropertyPathsToIndex)
 {
     innerPersister.Update(sagaData, sagaDataPropertyPathsToIndex);
 }
        public async Task Save_fails_when_writing_same_data_twice()
        {
            var saga = new TestSagaData
            {
                Id = Guid.NewGuid()
            };
            var persister = new InMemorySagaPersister();
            var insertSession = new InMemorySynchronizedStorageSession();
            await persister.Save(saga, SagaMetadataHelper.GetMetadata<TestSaga>(saga), insertSession, new ContextBag());
            await insertSession.CompleteAsync();

            var retrievingContext = new ContextBag();
            var returnedSaga1 = await persister.Get<TestSagaData>(saga.Id, new InMemorySynchronizedStorageSession(), retrievingContext);

            var winningSaveSession = new InMemorySynchronizedStorageSession();
            var losingSaveSession = new InMemorySynchronizedStorageSession();

            await persister.Update(returnedSaga1, winningSaveSession, retrievingContext);
            await persister.Update(returnedSaga1, losingSaveSession, retrievingContext);

            await winningSaveSession.CompleteAsync();

            Assert.That(async () => await losingSaveSession.CompleteAsync(), Throws.InstanceOf<Exception>().And.Message.StartsWith($"InMemorySagaPersister concurrency violation: saga entity Id[{saga.Id}] already saved."));
        }