/// <summary> /// Save the specified <paramref name="context"/> changes for the given <paramref name="saga"/>. /// </summary> /// <param name="saga">The current saga version for which the context applies.</param> /// <param name="context">The saga context containing the saga changes to be applied.</param> public Saga Save(Saga saga, SagaContext context) { Verify.NotNull(saga, nameof(saga)); Verify.NotNull(context, nameof(context)); var sagaType = saga.GetType(); var key = String.Concat(sagaType.GetFullNameWithAssembly(), "-", saga.CorrelationId); using (var sagaLock = new SagaLock(sagaType, saga.CorrelationId)) { sagaLock.Aquire(); try { sagaStore.Save(saga, context); if (saga.Completed) { memoryCache.Remove(key); } else { memoryCache.Set(key, saga, CreateCacheItemPolicy()); } return(saga); } catch (ConcurrencyException) { memoryCache.Remove(key); throw; } } }
/// <summary> /// Attempt to retrieve an existing saga instance identified by the specified <paramref name="type"/> and <paramref name="id"/>. /// </summary> /// <param name="type">The type of saga to be retrieved.</param> /// <param name="id">The correlation id of the saga to be retrieved.</param> /// <param name="saga">The <see cref="Saga"/> instance if found; otherwise <value>null</value>.</param> public Boolean TryGetSaga(Type type, Guid id, out Saga saga) { Verify.NotNull(type, nameof(type)); var key = String.Concat(type.GetFullNameWithAssembly(), "-", id); using (var sagaLock = new SagaLock(type, id)) { sagaLock.Aquire(); //NOTE: We do not want to cache a NULL saga reference, thus explicitly check for existance and add to cache if instance found. saga = (Saga)memoryCache.Get(key); if (saga == null && sagaStore.TryGetSaga(type, id, out saga)) { memoryCache.Add(key, saga, CreateCacheItemPolicy()); } } //NOTE: Given that saga state is modified during `Handling`, we must always return a copy of the cached instance. return((saga == null ? null : saga = saga.Copy()) != null); }
/// <summary> /// Attempt to retrieve an existing saga instance identified by the specified <paramref name="type"/> and <paramref name="id"/>. /// </summary> /// <param name="type">The type of saga to be retrieved.</param> /// <param name="id">The correlation id of the saga to be retrieved.</param> /// <param name="saga">The <see cref="Saga"/> instance if found; otherwise <value>null</value>.</param> public Boolean TryGetSaga(Type type, Guid id, out Saga saga) { Verify.NotNull(type, nameof(type)); var key = String.Concat(type.GetFullNameWithAssembly(), "-", id); using (var sagaLock = new SagaLock(type, id)) { sagaLock.Aquire(); //NOTE: We do not want to cache a NULL saga reference, thus explicitly check for existance and add to cache if instance found. saga = (Saga)memoryCache.Get(key); if (saga == null && sagaStore.TryGetSaga(type, id, out saga)) memoryCache.Add(key, saga, CreateCacheItemPolicy()); } //NOTE: Given that saga state is modified during `Handling`, we must always return a copy of the cached instance. return (saga == null ? null : saga = saga.Copy()) != null; }
/// <summary> /// Save the specified <paramref name="context"/> changes for the given <paramref name="saga"/>. /// </summary> /// <param name="saga">The current saga version for which the context applies.</param> /// <param name="context">The saga context containing the saga changes to be applied.</param> public Saga Save(Saga saga, SagaContext context) { Verify.NotNull(saga, nameof(saga)); Verify.NotNull(context, nameof(context)); var sagaType = saga.GetType(); var key = String.Concat(sagaType.GetFullNameWithAssembly(), "-", saga.CorrelationId); using (var sagaLock = new SagaLock(sagaType, saga.CorrelationId)) { sagaLock.Aquire(); try { sagaStore.Save(saga, context); if (saga.Completed) memoryCache.Remove(key); else memoryCache.Set(key, saga, CreateCacheItemPolicy()); return saga; } catch (ConcurrencyException) { memoryCache.Remove(key); throw; } } }