예제 #1
0
 public IExpectBuilder <T> Or(Type type, Func <object, bool> filter)
 {
     WaitIsOver = WaitIsOver.Or(c => c != null && c.Any(filter));
     Waiter.Subscribe(type, filter, WaitIsOver.Compile());
     Waiter.Subscribe(MessageMetadataEnvelop.GenericForType(type), filter, WaitIsOver.Compile());
     return(this);
 }
예제 #2
0
        public static CreateActorRouteMessage ForAggregate(string name, IAggregateCommandsHandlerDesriptor descriptor)
        {
            var messageRoutes = descriptor.RegisteredCommands.Select(c => new MessageRoute
                                                                     (
                                                                         MessageMetadataEnvelop.GenericForType(c.CommandType),
                                                                         c.Property
                                                                     )).ToArray();

            var hubType = typeof(AggregateHubActor <>).MakeGenericType(descriptor.AggregateType);

            return(new CreateActorRouteMessage(hubType, name, PoolKind.None, messageRoutes));
        }
예제 #3
0
        public static CreateActorRouteMessage ForSaga(ISagaDescriptor descriptor, string name = null)
        {
            name = name ?? $"SagaHub_{descriptor.SagaType.BeautyName()}";

            var messageRoutes = descriptor.AcceptMessages
                                .Select(messageBinder => new MessageRoute(
                                            MessageMetadataEnvelop.GenericForType(messageBinder.MessageType),
                                            messageBinder.CorrelationField))
                                .ToArray();

            var hubType = typeof(SagaHubActor <,>).MakeGenericType(descriptor.SagaType,
                                                                   descriptor.StateType);

            return(new CreateActorRouteMessage(hubType, name, PoolKind.None, messageRoutes));
        }
예제 #4
0
        public async Task <IWaitResults> Execute(params ICommand[] commands)
        {
            foreach (var command in commands)
            {
                _waiter.ExpectBuilder.Or(MessageMetadataEnvelop.GenericForType(Fault.TypeFor(command)),
                                         f => (((f as IMessageMetadataEnvelop)?.Message as IFault)?.Message as ICommand)?.Id == command.Id);
            }

            var task = _waiter.Start();

            foreach (var command in commands)
            {
                Executor.Execute(command);
            }

            var res = await task;

            if (!_failOnFaults)
            {
                return(res);
            }

            var faults = new List <IFault>();

            foreach (var m in res.All)
            {
                var fault = m as IFault;
                if (fault != null)
                {
                    faults.Add(fault);
                }

                var envelopedFault = m as IMessageMetadataEnvelop <IFault>;
                if (envelopedFault != null)
                {
                    faults.Add(envelopedFault.Message);
                }
            }

            if (faults.Any())
            {
                throw new AggregateException(faults.Select(f => f.Exception));
            }

            return(res);
        }
예제 #5
0
        public async Task <object> Execute(CommandPlan plan)
        {
            var waiter = new AkkaCommandLocalWaiter(this, _system, _transport, plan.Timeout, true);

            var expectBuilder = waiter.ExpectBuilder;

            //All expected messages should be received
            foreach (var expectedMessage in plan.ExpectedMessages.Where(e => !typeof(IFault).IsAssignableFrom(e.MessageType)))
            {
                expectBuilder.And(MessageMetadataEnvelop.GenericForType(expectedMessage.MessageType),
                                  o => expectedMessage.Match((o as IMessageMetadataEnvelop)?.Message));
            }


            //All expected faults should end waiting
            foreach (var expectedMessage in plan.ExpectedMessages.Where(e => typeof(IFault).IsAssignableFrom(e.MessageType)))
            {
                expectBuilder.Or(MessageMetadataEnvelop.GenericForType(expectedMessage.MessageType),
                                 o => expectedMessage.Match((o as IMessageMetadataEnvelop)?.Message) &&
                                 (!expectedMessage.Sources.Any() ||
                                  expectedMessage.Sources.Contains(((o as IMessageMetadataEnvelop)?.Message as IFault)?.Processor)));
            }

            //Command fault should always end waiting
            var commandFaultType = typeof(IFault <>).MakeGenericType(plan.Command.GetType());

            expectBuilder.Or(MessageMetadataEnvelop.GenericForType(commandFaultType),
                             o => (((o as IMessageMetadataEnvelop)?.Message as IFault)?.Message as ICommand)?.Id == plan.Command.Id);


            var res = await expectBuilder.Create(plan.Timeout)
                      .Execute(plan.Command)
                      .ConfigureAwait(false);

            return(res.All.Count > 1 ? res.All.ToArray() : res.All.FirstOrDefault());
        }