public SagaDispatchResult DispatchToSaga(string correlationId, object message, bool createNew, bool wait, SagaBase sagaHandler, Action<SagaBase> callback) { string sagaId = null; if (!sagaHandler.TryGetSagaIdFromMessage(message, out sagaId)) { sagaId = correlationId; } else { if (SagaBase.IGNORE_MESSAGE == sagaId) { return SagaDispatchResult.MessageHandled; } } if (!createNew && string.IsNullOrEmpty(sagaId)) { if (IgnoreMessagesWithoutSagaId) { return SagaDispatchResult.MessageHandled; } else throw new Exception("Saga Id could not be determined"); } bool b = ExclusiveLock(sagaId, wait, delegate() { DispatchToSagaInternal(sagaId, createNew, sagaHandler, callback); }); if (!b) { log.Info("Concurrent update of saga {0}, will process the message later", sagaId); } return b ? SagaDispatchResult.MessageHandled : SagaDispatchResult.ConcurrentUpdateHandleLater; }
protected void DispatchToSagaInternal(string sagaId, bool createNew, SagaBase sagaHandler, Action <SagaBase> callback) { string version = null; bool found = false; object sagaState = null; var st = Stopwatch.StartNew(); var sagaStateType = sagaHandler.GetType().BaseType.GetGenericArguments()[0]; //todo: what if inheritance is deeper??? if (!string.IsNullOrEmpty(sagaId)) { found = SagaStateRepo.Get(sagaId, sagaStateType, true, out sagaState, out version); } else //create new id { sagaId = Guid.NewGuid().ToString("N"); } if (!found) { if (!createNew) { throw new Exception("Saga instance not found: " + sagaId); } sagaState = Activator.CreateInstance(sagaStateType); version = "1"; } sagaHandler.IsNew = !found; sagaHandler.InitializeSagaState(sagaId, version, sagaState); callback(sagaHandler); if (sagaHandler.Completed) { if (!createNew) { SagaStateRepo.Delete(sagaId); log.Info("Deleted saga {0}/{1}", sagaHandler.GetType().Name, sagaId); } } else { sagaHandler.BeforeSave(); if (!found) { SagaStateRepo.InsertNew(sagaHandler.Id, sagaState); log.Info("Saved new saga {0}/{1}", sagaHandler.GetType().Name, sagaId); } else { SagaStateRepo.Update(sagaHandler.Id, sagaState, version); log.Debug("Updated saga {0}/{1}", sagaHandler.GetType().Name, sagaId); } } st.Stop(); statLog.Info("Dispatch:{0}", st.ElapsedMilliseconds); }
public EfSagaRecord(SagaBase saga, List<SagaCorrelationProperty> sagaCorrelationIds) : base(saga.SagaId) { Guard.ArgumentNotNull(saga, nameof(saga)); Guard.ArgumentNotNull(sagaCorrelationIds, nameof(sagaCorrelationIds)); var sagaState = saga.SagaState; var sagaStateType = sagaState.State.GetType(); StateType = sagaStateType.AssemblyQualifiedName; SagaState = ContractlessMessagePackSerializer.Instance.BinarySerialize(sagaState.State, sagaStateType); SagaVersion = sagaState.SagaVersion; foreach (var message in sagaState.Messages) { this.RaiseEvent(message); } sagaState.Messages.Clear(); CorrelationIds = sagaCorrelationIds.Select(id => new EfSagaCorrelationId(Id, saga.GetType().Name, id.PropertyName, id.PropertyValue)).ToList(); }
// here we need to attach Saga public void SaveSaga(SagaBase saga, List <SagaCorrelationProperty> correlationIds) { using (var db = _contextFactory()) { var record = new EfSagaRecord(saga, correlationIds); if (record.SagaVersion == 1) { db.Sagas.Add(record); } else { db.Sagas.Update(record); db.Entry(record).Property("SagaVersion").OriginalValue = (saga.SagaState.SagaVersion - 1); } db.SaveChanges(); } }
public List <SagaCorrelationProperty> GetCorrelationIdsFromSaga(SagaBase saga) { if (saga.GetType() != SagaType) { throw new InvalidOperationException("Wrong Saga Type"); } List <SagaCorrelationProperty> result = new List <SagaCorrelationProperty>(); foreach (var config in EventMappings.Values.DistinctBy(v => v.SagaPropertyName)) { var value = config.SagaPropertyFunc(saga.SagaState.State); if (value == null || object.Equals(GetDefault(value.GetType()), value)) { continue; } result.Add(new SagaCorrelationProperty(config.SagaPropertyName, value.ToString())); } return(result); }
public SagaDispatchResult DispatchToSaga(string correlationId, object message, bool createNew, bool wait, SagaBase sagaHandler, Action <SagaBase> callback) { string sagaId = null; if (!sagaHandler.TryGetSagaIdFromMessage(message, out sagaId)) { sagaId = correlationId; } else { if (SagaBase.IGNORE_MESSAGE == sagaId) { return(SagaDispatchResult.MessageHandled); } } if (!createNew && string.IsNullOrEmpty(sagaId)) { if (IgnoreMessagesWithoutSagaId) { return(SagaDispatchResult.MessageHandled); } else { throw new Exception("Saga Id could not be determined"); } } bool b = ExclusiveLock(sagaId, wait, delegate() { DispatchToSagaInternal(sagaId, createNew, sagaHandler, callback); }); if (!b) { log.Info("Concurrent update of saga {0}, will process the message later", sagaId); } return(b ? SagaDispatchResult.MessageHandled : SagaDispatchResult.ConcurrentUpdateHandleLater); }
public SendNotificationToAdministrator(SagaBase saga) : base(saga) { }
public SendGreetingEmail(SagaBase saga) : base(saga) { }
protected void DispatchToSagaInternal(string sagaId, bool createNew, SagaBase sagaHandler, Action<SagaBase> callback) { string version = null; bool found = false; object sagaState = null; var st = Stopwatch.StartNew(); var sagaStateType = sagaHandler.GetType().BaseType.GetGenericArguments()[0]; //todo: what if inheritance is deeper??? if (!string.IsNullOrEmpty(sagaId)) { found = SagaStateRepo.Get(sagaId, sagaStateType, true, out sagaState, out version); } else //create new id { sagaId = Guid.NewGuid().ToString("N"); } if (!found) { if (!createNew) throw new Exception("Saga instance not found: " + sagaId); sagaState = Activator.CreateInstance(sagaStateType); version = "1"; } sagaHandler.IsNew = !found; sagaHandler.InitializeSagaState(sagaId, version, sagaState); callback(sagaHandler); if (sagaHandler.Completed) { if (!createNew) { SagaStateRepo.Delete(sagaId); log.Info("Deleted saga {0}/{1}", sagaHandler.GetType().Name, sagaId); } } else { sagaHandler.BeforeSave(); if (!found) { SagaStateRepo.InsertNew(sagaHandler.Id, sagaState); log.Info("Saved new saga {0}/{1}", sagaHandler.GetType().Name, sagaId); } else { SagaStateRepo.Update(sagaHandler.Id, sagaState, version); log.Debug("Updated saga {0}/{1}", sagaHandler.GetType().Name, sagaId); } } st.Stop(); statLog.Info("Dispatch:{0}", st.ElapsedMilliseconds); }