public void Invoke(ReceiveLogicalMessageContext context, Action next) { var messageToHandle = context.LogicalMessage; // for now we cheat and pull it from the behavior context: var callbackInvoked = context.Get <bool>(CallbackInvocationBehavior.CallbackInvokedKey); var handlerTypedToInvoke = HandlerRegistry.GetHandlerTypes(messageToHandle.MessageType).ToList(); if (!callbackInvoked && !handlerTypedToInvoke.Any()) { var error = string.Format("No handlers could be found for message type: {0}", messageToHandle.MessageType); throw new InvalidOperationException(error); } foreach (var handlerType in handlerTypedToInvoke) { var loadedHandler = new MessageHandler { Instance = context.Builder.Build(handlerType), Invocation = (handlerInstance, message) => HandlerInvocationCache.InvokeHandle(handlerInstance, message) }; if (PipelineFactory.InvokeHandlerPipeline(loadedHandler).ChainAborted) { //if the chain was aborted skip the other handlers break; } } next(); }
public void Should_invoke_handle_method() { HandlerInvocationCache.CacheMethodForHandler(typeof(StubHandler), typeof(StubMessage)); var handler = new StubHandler(); HandlerInvocationCache.InvokeHandle(handler, new StubMessage()); Assert.IsTrue(handler.HandleCalled); }
public void Should_have_passed_through_correct_message() { HandlerInvocationCache.CacheMethodForHandler(typeof(StubHandler), typeof(StubMessage)); var handler = new StubHandler(); var stubMessage = new StubMessage(); HandlerInvocationCache.InvokeHandle(handler, stubMessage); Assert.AreEqual(stubMessage, handler.HandledMessage); }
public void AddHandler(Type messageType, object handler) { List <LoadedHandler> handlersForMessage; var loadedHandler = new LoadedHandler { Instance = handler, Invocation = (handlerInstance, message) => HandlerInvocationCache.InvokeHandle(handlerInstance, message) }; if (!messageHandlers.TryGetValue(messageType, out handlersForMessage)) { messageHandlers[messageType] = new List <LoadedHandler> { loadedHandler }; } else { handlersForMessage.Add(loadedHandler); } }
public void RunNew() { HandlerInvocationCache.CacheMethodForHandler(typeof(StubMessageHandler), typeof(StubMessage)); HandlerInvocationCache.CacheMethodForHandler(typeof(StubTimeoutHandler), typeof(StubTimeoutState)); var handler1 = new StubMessageHandler(); var handler2 = new StubTimeoutHandler(); var stubMessage1 = new StubMessage(); var stubMessage2 = new StubTimeoutState(); HandlerInvocationCache.InvokeHandle(handler1, stubMessage1); HandlerInvocationCache.InvokeHandle(handler2, stubMessage2); var startNew = Stopwatch.StartNew(); for (var i = 0; i < 100000; i++) { HandlerInvocationCache.InvokeHandle(handler1, stubMessage1); HandlerInvocationCache.InvokeHandle(handler2, stubMessage2); } startNew.Stop(); Trace.WriteLine(startNew.ElapsedMilliseconds); }
/// <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) { var entitiesHandled = new List <IContainSagaData>(); var sagaTypesHandled = new List <Type>(); foreach (var finder in GetFindersFor(message, builder)) { var sagaEntityIsPersistent = true; var sagaEntity = UseFinderToFindSaga(finder, message); Type sagaType; if (sagaEntity == null) { sagaType = Features.Sagas.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 = Features.Sagas.GetSagaTypeForSagaEntityType(sagaEntity.GetType()); } if (messageHandlerType.IsAssignableFrom(sagaType)) { yield return () => { var saga = (ISaga)builder.Build(sagaType); saga.Entity = sagaEntity; try { SagaContext.Current = saga; if (IsTimeoutMessage(message)) { HandlerInvocationCache.InvokeTimeout(saga, message); } else { HandlerInvocationCache.InvokeHandle(saga, message); } if (!saga.Completed) { if (!sagaEntityIsPersistent) { Persister.Save(saga.Entity); } else { Persister.Update(saga.Entity); } } else { if (sagaEntityIsPersistent) { Persister.Complete(saga.Entity); } if (saga.Entity.Id != Guid.Empty) { 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); } } } ; } IContainSagaData CreateNewSagaEntity(Type sagaType) { var sagaEntityType = Features.Sagas.GetSagaEntityTypeForSagaType(sagaType); if (sagaEntityType == null) { throw new InvalidOperationException("No saga entity type could be found for saga: " + sagaType); } var sagaEntity = (IContainSagaData)Activator.CreateInstance(sagaEntityType); sagaEntity.Id = CombGuid.Generate(); if (Bus.CurrentMessageContext.ReplyToAddress != null) { sagaEntity.Originator = Bus.CurrentMessageContext.ReplyToAddress.ToString(); } sagaEntity.OriginalMessageId = Bus.CurrentMessageContext.Id; return(sagaEntity); }