예제 #1
0
        private PollerState FindOrCreateState(IContractsRegistry contractsRegistry, List <PollerState> pollerStates, string sourceContractName, Type handlerType)
        {
            var handlerContractName = contractsRegistry.GetContractName(handlerType);

            PollerState state = null;

            foreach (var x in pollerStates)
            {
                if (x.HandlerContractName != handlerContractName || x.SourceContractName != sourceContractName)
                {
                    continue;
                }
                state = x;
                break;
            }
            if (state != null)
            {
                return(state);
            }
            state = new PollerState(_pollerContractName, sourceContractName, handlerContractName);
            pollerStates.Add(state);
            return(state);
        }
예제 #2
0
        private async Task <bool> TryDispatch(PollerContext ctx, HandlerRegistrar.HandlerTypeInfo handlerInfo, EventEnvelope envelope, PollerState state)
        {
            var eventType      = envelope.Event.GetType();
            var shouldDispatch = handlerInfo.ContainsEventType(eventType);

            if (shouldDispatch)
            {
                PreHandleEvent(envelope, handlerInfo.HandlerType);
            }

            using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew, _transactionOptions, TransactionScopeAsyncFlowOption.Enabled))
            {
                if (shouldDispatch)
                {
                    var handlerInstance = CreateHandlerInstance(handlerInfo.HandlerType);
                    if (handlerInstance == null)
                    {
                        throw new NullReferenceException($"Handler instance {handlerInfo.HandlerType.FullName} is null.");
                    }
                    ctx.Logger.Trace("Dispatching event {0} to {1}...", eventType.FullName, handlerInfo.HandlerType.FullName);
                    if (handlerInfo.IsAsync)
                    {
                        await((dynamic)handlerInstance).Handle((dynamic)envelope.Event, envelope);
                    }
                    else
                    {
                        ((dynamic)handlerInstance).Handle((dynamic)envelope.Event, envelope);
                    }
                }

                state.EventSequenceId = envelope.SequenceId;

                if (shouldDispatch)
                {
                    await ctx.StateRepository.InsertOrUpdateAsync(state);

                    state.Clear();
                    ctx.Logger.Trace("Dispatched event {0} by {1} saved with sequence {2}.", eventType.FullName, handlerInfo.HandlerType.FullName, state.EventSequenceId);
                }
                else
                {
                    ctx.Logger.Trace("Dispatched event {0} by {1} marked as dirty with sequence {2}.", eventType.FullName, handlerInfo.HandlerType.FullName, state.EventSequenceId);
                }
                scope.Complete();
            }
            if (shouldDispatch)
            {
                PostHandleEvent(envelope, handlerInfo.HandlerType);
            }
            return(shouldDispatch);
        }