/// <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> /// When overriden, defines the custom behavior to be invoked after attempting to save the specified <paramref name="saga"/>. /// </summary> /// <param name="saga">The modified <see cref="Saga"/> instance if <paramref name="error"/> is <value>null</value>; otherwise the original <see cref="Saga"/> instance if <paramref name="error"/> is not <value>null</value>.</param> /// <param name="context">The current <see cref="SagaContext"/> assocaited with the pending saga modifications.</param> /// <param name="error">The <see cref="Exception"/> thrown if the save was unsuccessful; otherwise <value>null</value>.</param> public override void PostSave(Saga saga, SagaContext context, Exception error) { if (!context.TimeoutChanged || saga == null || error != null) { return; } if (saga.Timeout.HasValue && !saga.Completed) { var timeout = saga.Timeout.Value; TimeoutCache.ScheduleTimeout(new SagaTimeout(saga.GetType(), saga.CorrelationId, timeout)); } else { TimeoutCache.ClearTimeout(new SagaReference(saga.GetType(), saga.CorrelationId)); } RescheduleTimer(TimeoutCache.GetNextScheduledTimeout()); }
/// <summary> /// When overriden, defines the custom behavior to be invoked after attempting to save the specified <paramref name="saga"/>. /// </summary> /// <param name="saga">The modified <see cref="Saga"/> instance if <paramref name="error"/> is <value>null</value>; otherwise the original <see cref="Saga"/> instance if <paramref name="error"/> is not <value>null</value>.</param> /// <param name="context">The current <see cref="SagaContext"/> assocaited with the pending saga modifications.</param> /// <param name="error">The <see cref="Exception"/> thrown if the save was unsuccessful; otherwise <value>null</value>.</param> public override void PostSave(Saga saga, SagaContext context, Exception error) { if (!context.TimeoutChanged || saga == null || error != null) return; if (saga.Timeout.HasValue && !saga.Completed) { var timeout = saga.Timeout.Value; TimeoutCache.ScheduleTimeout(new SagaTimeout(saga.GetType(), saga.CorrelationId, timeout)); } else { TimeoutCache.ClearTimeout(new SagaReference(saga.GetType(), saga.CorrelationId)); } RescheduleTimer(TimeoutCache.GetNextScheduledTimeout()); }
/// <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; } } }