/// <summary> /// Get Dispatcher /// </summary> /// <param name="messageHandlerType">Type of the message Handler</param> /// <param name="builder">Builder</param> /// <param name="message">Message</param> /// <returns>Saga Dispatcher</returns> public IEnumerable <Action> GetDispatcher(Type messageHandlerType, IBuilder builder, object message) { if (message.IsTimeoutMessage() && !message.TimeoutHasExpired()) { yield return(() => Bus.HandleCurrentMessageLater()); yield break; } var entitiesHandled = new List <ISagaEntity>(); var sagaTypesHandled = new List <Type>(); foreach (var finder in GetFindersFor(message, builder)) { bool sagaEntityIsPersistent = true; ISagaEntity sagaEntity = UseFinderToFindSaga(finder, message); Type sagaType; if (sagaEntity == null) { sagaType = Configure.GetSagaTypeToStartIfMessageNotFoundByFinder(message, finder); if (sagaType == null) { continue; } if (sagaTypesHandled.Contains(sagaType)) { continue; // don't create the same saga type twice for the same message } sagaEntity = CreateNewSagaEntity(sagaType); sagaEntityIsPersistent = false; } else { if (entitiesHandled.Contains(sagaEntity)) { continue; // don't call the same saga twice } sagaType = Configure.GetSagaTypeForSagaEntityType(sagaEntity.GetType()); } if (messageHandlerType.IsAssignableFrom(sagaType)) { yield return () => { var saga = (ISaga)builder.Build(sagaType); saga.Entity = sagaEntity; try { SagaContext.Current = saga; HandlerInvocationCache.Invoke(saga, message); if (!saga.Completed) { if (!sagaEntityIsPersistent) { Persister.Save(saga.Entity); } else { Persister.Update(saga.Entity); } } else { if (sagaEntityIsPersistent) { Persister.Complete(saga.Entity); } NotifyTimeoutManagerThatSagaHasCompleted(saga); } LogIfSagaIsFinished(saga); } finally { SagaContext.Current = null; } } } ; sagaTypesHandled.Add(sagaType); entitiesHandled.Add(sagaEntity); } if (entitiesHandled.Count == 0) { yield return () => { logger.InfoFormat("Could not find a saga for the message type {0} with id {1}. Going to invoke SagaNotFoundHandlers.", message.GetType().FullName, Bus.CurrentMessageContext.Id); foreach (var handler in builder.BuildAll <IHandleSagaNotFound>()) { logger.DebugFormat("Invoking SagaNotFoundHandler: {0}", handler.GetType().FullName); handler.Handle(message); } } } ; } ISagaEntity CreateNewSagaEntity(Type sagaType) { var sagaEntityType = Configure.GetSagaEntityTypeForSagaType(sagaType); if (sagaEntityType == null) { throw new InvalidOperationException("No saga entity type could be found for saga: " + sagaType); } var sagaEntity = (ISagaEntity)Activator.CreateInstance(sagaEntityType); sagaEntity.Id = GuidCombGenerator.Generate(); sagaEntity.Originator = Bus.CurrentMessageContext.ReplyToAddress.ToString(); sagaEntity.OriginalMessageId = Bus.CurrentMessageContext.Id; return(sagaEntity); }
/// <summary> /// Generates a new id for a saga. /// </summary> /// <returns></returns> public virtual Guid GenerateSagaId() { return(GuidCombGenerator.Generate()); }
/// <summary> /// Generates a new id for a saga. /// </summary> /// <returns></returns> Guid GenerateSagaId() { return(GuidCombGenerator.Generate()); }