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))); }
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); }
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); }
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 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))); }
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 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); }