示例#1
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."));
        }
        public void Save_process_is_repeatable()
        {
            var saga = new TestSagaData {
                Id = Guid.NewGuid()
            };

            persister.Save(saga);

            var returnedSaga1 = Task <TestSagaData> .Factory.StartNew(() => persister.Get <TestSagaData>(saga.Id)).Result;

            var returnedSaga2 = persister.Get <TestSagaData>("Id", saga.Id);

            persister.Save(returnedSaga1);
            var exceptionFromSaga2 = Assert.Throws <Exception>(() => persister.Save(returnedSaga2));

            Assert.IsTrue(exceptionFromSaga2.Message.StartsWith(string.Format("InMemorySagaPersister concurrency violation: saga entity Id[{0}] already saved by [Worker.", saga.Id)));

            var returnedSaga3 = Task <TestSagaData> .Factory.StartNew(() => persister.Get <TestSagaData>("Id", saga.Id)).Result;

            var returnedSaga4 = persister.Get <TestSagaData>(saga.Id);

            persister.Save(returnedSaga4);

            var exceptionFromSaga3 = Assert.Throws <Exception>(() => persister.Save(returnedSaga3));

            Assert.IsTrue(exceptionFromSaga3.Message.StartsWith(string.Format("InMemorySagaPersister concurrency violation: saga entity Id[{0}] already saved by [Worker.", saga.Id)));
        }
示例#3
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 returnedSaga1 = await persister.Get <TestSagaData>(saga.Id, new InMemorySynchronizedStorageSession(), new ContextBag());

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

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

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

            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 Should_delete_the_saga()
        {
            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 intentionallySharedContext = new ContextBag();
            var sagaData = await persister.Get <TestSagaData>(saga.Id, new InMemorySynchronizedStorageSession(), intentionallySharedContext);

            var deleteSession = new InMemorySynchronizedStorageSession();
            await persister.Complete(saga, deleteSession, intentionallySharedContext);

            await deleteSession.CompleteAsync();

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

            Assert.NotNull(sagaData);
            Assert.Null(completedSaga);
        }
示例#5
0
        public void Should_delete_the_saga()
        {
            var saga = new TestSagaData {
                Id = Guid.NewGuid()
            };

            persister.Save(saga);
            Assert.NotNull(persister.Get <TestSagaData>(saga.Id));
            persister.Complete(saga);
            Assert.Null(persister.Get <TestSagaData>(saga.Id));
        }
        public void Persister_returns_different_instance_of_saga_data()
        {
            var saga = new TestSagaData {
                Id = Guid.NewGuid()
            };

            persister.Save(saga);

            var returnedSaga1 = persister.Get <TestSagaData>(saga.Id);
            var returnedSaga2 = persister.Get <TestSagaData>("Id", saga.Id);

            Assert.AreNotSame(returnedSaga2, returnedSaga1);
            Assert.AreNotSame(returnedSaga1, saga);
            Assert.AreNotSame(returnedSaga2, saga);
        }
示例#7
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."));
        }
示例#8
0
        public void Save_fails_when_data_changes_between_read_and_update_on_same_thread()
        {
            var saga = new TestSagaData {
                Id = Guid.NewGuid()
            };

            persister.Save(saga);

            var record      = persister.Get <TestSagaData>(saga.Id);
            var staleRecord = persister.Get <TestSagaData>("Id", saga.Id);

            persister.Save(record);
            var exception = Assert.Throws <Exception>(() => persister.Save(staleRecord));

            Assert.IsTrue(exception.Message.StartsWith(string.Format("InMemorySagaPersister concurrency violation: saga entity Id[{0}] already saved.", saga.Id)));
        }
        public void Save_fails_when_data_changes_between_read_and_update()
        {
            var saga = new TestSagaData {
                Id = Guid.NewGuid()
            };

            persister.Save(saga);

            var returnedSaga1 = Task <TestSagaData> .Factory.StartNew(() => persister.Get <TestSagaData>(saga.Id)).Result;

            var returnedSaga2 = persister.Get <TestSagaData>("Id", saga.Id);

            persister.Save(returnedSaga1);
            var exception = Assert.Throws <Exception>(() => persister.Save(returnedSaga2));

            Assert.IsTrue(exception.Message.StartsWith(string.Format("InMemorySagaPersister concurrency violation: saga entity Id[{0}] already saved by [Worker.", saga.Id)));
        }
示例#10
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>());
        }
示例#11
0
        public async Task Persister_returns_different_instance_of_saga_data()
        {
            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 returnedSaga1 = await persister.Get <TestSagaData>(saga.Id, new InMemorySynchronizedStorageSession(), new ContextBag());

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

            Assert.AreNotSame(returnedSaga2, returnedSaga1);
            Assert.AreNotSame(returnedSaga1, saga);
            Assert.AreNotSame(returnedSaga2, saga);
        }