Пример #1
0
 /// <summary>
 /// Directly inject messages into actor receive behavior. Any exceptions
 /// thrown will be available to you, while still being able to use
 /// become/unbecome.
 /// </summary>
 /// <param name="message">The message.</param>
 /// <param name="sender">The sender.</param>
 public void Receive(object message, IActorRef sender = null)
 {
     var cell = Cell;
     sender = sender.IsNobody() ? cell.System.DeadLetters : sender;
     var envelope = new Envelope { Message = message, Sender = sender };
     cell.UseThreadContext(() => cell.ReceiveMessageForTest(envelope));
 }
Пример #2
0
 protected override void TellInternal(object message, IActorRef sender)
 {
     if(message == null) throw new InvalidMessageException("Message is null");
     var d = message as DeadLetter;
     if (d != null) SpecialHandle(d.Message, d.Sender);
     else if (!SpecialHandle(message, sender))
     {
         _eventStream.Publish(new DeadLetter(message, sender.IsNobody() ? _provider.DeadLetters : sender, this));
     }
 }
Пример #3
0
 protected virtual void SendUserMessage(object message, IActorRef sender)
 {
     if(message == null) throw new InvalidMessageException();
     var deadLetter = message as DeadLetter;
     if(deadLetter != null)
         HandleDeadLetter(deadLetter);
     else
     {
         var wasHandled = SpecialHandle(message, sender);
         if(!wasHandled)
         {
             _eventStream.Publish(new DeadLetter(message, sender.IsNobody() ? _provider.DeadLetters : sender, this));
         }
     }
 }
Пример #4
0
        protected virtual bool SpecialHandle(object message, IActorRef sender)
        {
            var watch = message as Watch;
            if (watch != null)
            {
                if (watch.Watchee.Equals(this) && !watch.Watcher.Equals(this))
                {
                    watch.Watcher.SendSystemMessage(new DeathWatchNotification(watch.Watchee, existenceConfirmed: false, addressTerminated: false));
                }
                return true;
            }
            if (message is Unwatch)
                return true;    //Just ignore

            var identify = message as Identify;
            if (identify != null)
            {
                sender.Tell(new ActorIdentity(identify.MessageId, null));
                return true;
            }

            var actorSelectionMessage = message as ActorSelectionMessage;
            if (actorSelectionMessage != null)
            {
                var selectionIdentify = actorSelectionMessage.Message as Identify;
                if (selectionIdentify != null)
                {
                    if (!actorSelectionMessage.WildCardFanOut)
                        sender.Tell(new ActorIdentity(selectionIdentify.MessageId, null));
                }
                else
                {
                    _eventStream.Publish(new DeadLetter(actorSelectionMessage.Message, sender.IsNobody() ? _provider.DeadLetters : sender, this));
                }
                return true;
            }

            var deadLetterSuppression = message as IDeadLetterSuppression;
            if (deadLetterSuppression != null)
            {
                _eventStream.Publish(new SuppressedDeadLetter(deadLetterSuppression, sender.IsNobody() ? _provider.DeadLetters : sender, this));
                return true;
            }

            return false;
        }
Пример #5
0
        private void CheckChange()
        {
            if (_PremiseChangeStateActorRef.IsNobody())
            {
                return;
            }

            if (attributeRemoteControlState != oldAttributeRemoteControlState)
            {
                if (attributeRemoteControlState == (int)RemoteControlState.ButtonPress)
                {
                    _PremiseChangeStateActorRef.Tell(PremiseAction.MakeTrue);
                }
                else if (attributeRemoteControlState == (int)RemoteControlState.Off)
                {
                    _PremiseChangeStateActorRef.Tell(PremiseAction.MakeFalse);
                }
                oldAttributeRemoteControlState = attributeRemoteControlState;
            }
        }
Пример #6
0
        protected virtual void SendUserMessage(object message, IActorRef sender)
        {
            if (message == null)
            {
                throw new InvalidMessageException();
            }
            var deadLetter = message as DeadLetter;

            if (deadLetter != null)
            {
                HandleDeadLetter(deadLetter);
            }
            else
            {
                var wasHandled = SpecialHandle(message, sender);
                if (!wasHandled)
                {
                    _eventStream.Publish(new DeadLetter(message, sender.IsNobody() ? _provider.DeadLetters : sender, this));
                }
            }
        }
Пример #7
0
        protected override void OnReceive(object message)
        {
            if (message is ActorReference)
            {
                var temp = message as ActorReference;
                if (temp.ActorRefID == ActorRefType.FBEGateRef)
                {
                    SetFBEGateActorRef(temp.Ref);
                }
                if (temp.ActorRefID == ActorRefType.FBERemoteControlRef)
                {
                    SetFBERemoteControl(temp.Ref);
                }
                Sender.Tell(true);
            }
            else
            {
                switch (message)
                {
                case ConditionAction.SendClock:
                    if (!_FBEGateActorRef.IsNobody() && isGateOpen == false)
                    {
                        _FBEGateActorRef.Tell(GateAction.Open);
                    }
                    break;

                case ConditionAction.SendTrue:
                    isGateOpen = true;
                    if (!_FBERemoteControlRef.IsNobody())
                    {
                        _FBERemoteControlRef.Tell(RemoteControlState.ChangeComplete);
                    }
                    break;

                case ConditionAction.SendFalse:
                    isGateOpen = false;
                    break;
                }
            }
        }
Пример #8
0
        private void CheckChange()
        {
            if (_PremiseIsClosedActorRef.IsNobody() || _PremiseIsOpenActorRef.IsNobody())
            {
                return;
            }

            if (attributeGateState != oldAttributeGateState)
            {
                if (attributeGateState == (int)GateState.Closed)
                {
                    _PremiseIsClosedActorRef.Tell(PremiseAction.MakeTrue);
                    _PremiseIsOpenActorRef.Tell(PremiseAction.MakeFalse);
                }
                else if (attributeGateState == (int)GateState.Open)
                {
                    _PremiseIsClosedActorRef.Tell(PremiseAction.MakeFalse);
                    _PremiseIsOpenActorRef.Tell(PremiseAction.MakeTrue);
                }
                oldAttributeGateState = attributeGateState;
            }
        }
        private void ProcessResourceMsgHandler(ProcessResourceMsg msg)
        {
            _logger.Info(
                $"ProcessResourceMsgHandler for {msg.Resource} Epoch={msg.Resource.Content?.MatchStatus}{(msg.Resource.IsMatchOver ? $" isMatchOver=true": "")}");


            if (msg.Resource.Content == null)
            {
                _logger.Info($"ProcessResourceMsgHandler for {msg.Resource} content=NULL terminating");
                return;
            }

            IActorRef streamListenerActor = Context.Child(StreamListenerActor.GetName(msg.Resource.Id));

            if (streamListenerActor.IsNobody())
            {
                var fixtureState = GetFixtureState(msg.Resource);
                if (fixtureState != null && fixtureState.Sequence > msg.Resource.Content.Sequence)
                {
                    _logger.Info($"ProcessResourceMsgHandler for {msg.Resource} message is too old: messageSequence={msg.Resource.Content.Sequence} stateSequence={fixtureState.Sequence} terminating");
                    return;
                }

                _logger.Info(
                    $"Stream listener for {msg.Resource} doesn't exist. Going to trigger creation.");
                _streamListenerBuilderActorRef.Tell(new CreateStreamListenerMsg {
                    Resource = msg.Resource
                });
            }
            else
            {
                _logger.Info(
                    $"Stream listener for {msg.Resource} already exists. Going to trigger stream health check.");
                streamListenerActor.Tell(new StreamHealthCheckMsg {
                    Resource = msg.Resource, Time = DateTime.Now
                });
            }
        }
Пример #10
0
            private void Runner()
            {
                if (!_sendBack || _sender.IsNobody())
                {
                    return;
                }

                var errors = new List <string>();
                var fail   = false;

                foreach (var result in _results)
                {
                    if (result.IsOk)
                    {
                        continue;
                    }

                    fail = true;
                    errors.AddRange(result.Errors.OrElse(Array.Empty <string>));
                }

                _sender.Tell(fail ? OperationResult.Failure(errors.Select(s => new Error(null, s)), _action) : OperationResult.Success(_action), ActorRefs.NoSender);
            }
        private void ProcessResourceMsgHandler(ProcessResourceMsg msg)
        {
            _logger.Info(
                $"ProcessResourceMsgHandler for {msg.Resource} Epoch={msg.Resource.Content.MatchStatus}");
            IActorRef streamListenerActor = Context.Child(StreamListenerActor.GetName(msg.Resource.Id));

            if (streamListenerActor.IsNobody())
            {
                _logger.Info(
                    $"Stream listener for {msg.Resource} doesn't exist. Going to trigger creation.");
                _streamListenerBuilderActorRef.Tell(new CreateStreamListenerMsg {
                    Resource = msg.Resource
                });
            }
            else
            {
                _logger.Info(
                    $"Stream listener for {msg.Resource} already exists. Going to trigger stream health check.");
                streamListenerActor.Tell(new StreamHealthCheckMsg {
                    Resource = msg.Resource
                });
            }
        }
Пример #12
0
        private Task <SetThrottleAck> AskModeWithDeathCompletion(IActorRef target, ThrottleMode mode, TimeSpan timeout)
        {
            if (target.IsNobody())
            {
                return(Task.FromResult(SetThrottleAck.Instance));
            }
            else
            {
                return(target.Ask <SetThrottleAck>(mode, timeout));

                //TODO: use PromiseActorRef here when implemented
                //var internalTarget = target.AsInstanceOf<InternalActorRef>();
                //var promiseRef = PromiseActorRef.Apply(internalTarget.Provider, timeout, target, mode.GetType().Name);
                //internalTarget.Tell(new Watch(internalTarget, promiseRef));
                //target.Tell(mode, promiseRef);
                //return promiseRef.Result.Task.ContinueWith(tr =>
                //{
                //    if (tr.Result is Status.Success)
                //    {
                //        var resultMsg = tr.Result as Status.Success;
                //        if (resultMsg.Status is Terminated &&
                //            resultMsg.Status.AsInstanceOf<Terminated>().ActorRef.Path == target.Path)
                //            return SetThrottleAck.Instance;
                //        if (resultMsg.Status is SetThrottleAck)
                //        {
                //            internalTarget.Tell(new Unwatch(target, promiseRef));
                //        }
                //        return SetThrottleAck.Instance;
                //    }
                //    else
                //    {
                //        internalTarget.Tell(new Unwatch(target, promiseRef));
                //       return SetThrottleAck.Instance;
                //    }
                //}, TaskContinuationOptions.AttachedToParent & TaskContinuationOptions.ExecuteSynchronously);
            }
        }
Пример #13
0
 protected virtual bool SpecialHandle(object message, IActorRef sender)
 {
     var w = message as Watch;
     if(w != null)
     {
         if(w.Watchee == this && w.Watcher != this)
         {
             w.Watcher.Tell(new DeathWatchNotification(w.Watchee, existenceConfirmed: false, addressTerminated: false));
         }
         return true;
     }
     if(message is Unwatch)
         return true;    //Just ignore
     var identify = message as Identify;
     if(identify != null)
     {
         sender.Tell(new ActorIdentity(identify.MessageId, null));
         return true;
     }
     var sel = message as ActorSelectionMessage;
     if(sel != null)
     {
         var selectionIdentify = sel.Message as Identify;
         if(selectionIdentify != null)
         {
             if(!sel.WildCardFanOut)
                 sender.Tell(new ActorIdentity(selectionIdentify.MessageId, null));
         }
         else
         {
             _eventStream.Publish(new DeadLetter(sel.Message, sender.IsNobody() ? _provider.DeadLetters : sender, this));
         }
         return true;
     }
     return false;
 }
Пример #14
0
 /// <summary>
 /// Returns the <paramref name="actorRef"/>'s value if it's not <see langword="null"/>, <see cref="Nobody"/>,
 /// or <see cref="DeadLetterActorRef"/>. Otherwise return the result of evaluating `elseValue`.
 /// </summary>
 /// <param name="actorRef">The actor that is being tested.</param>
 /// <param name="elseValue">TBD</param>
 public static IActorRef GetOrElse(this IActorRef actorRef, Func <IActorRef> elseValue)
 {
     return(actorRef.IsNobody() ? elseValue() : actorRef);
 }
Пример #15
0
        protected virtual bool SpecialHandle(object message, IActorRef sender)
        {
            var watch = message as Watch;

            if (watch != null)
            {
                if (watch.Watchee.Equals(this) && !watch.Watcher.Equals(this))
                {
                    watch.Watcher.SendSystemMessage(new DeathWatchNotification(watch.Watchee, existenceConfirmed: false, addressTerminated: false));
                }
                return(true);
            }
            if (message is Unwatch)
            {
                return(true);    //Just ignore
            }
            var identify = message as Identify;

            if (identify != null)
            {
                sender.Tell(new ActorIdentity(identify.MessageId, null));
                return(true);
            }

            var actorSelectionMessage = message as ActorSelectionMessage;

            if (actorSelectionMessage != null)
            {
                var selectionIdentify = actorSelectionMessage.Message as Identify;
                if (selectionIdentify != null)
                {
                    if (!actorSelectionMessage.WildCardFanOut)
                    {
                        sender.Tell(new ActorIdentity(selectionIdentify.MessageId, null));
                    }
                }
                else
                {
                    _eventStream.Publish(new DeadLetter(actorSelectionMessage.Message, sender.IsNobody() ? _provider.DeadLetters : sender, this));
                }
                return(true);
            }

            // TODO: DeadLetterSupression

            return(false);
        }
Пример #16
0
 private void PublishSupressedDeadLetter(IDeadLetterSuppression msg, IActorRef sender)
 {
     _eventStream.Publish(new SuppressedDeadLetter(msg, sender.IsNobody() ? _provider.DeadLetters : sender, this));
 }
Пример #17
0
        /// <summary>
        /// TBD
        /// </summary>
        /// <param name="message">TBD</param>
        /// <param name="sender">TBD</param>
        /// <returns>TBD</returns>
        protected virtual bool SpecialHandle(object message, IActorRef sender)
        {
            if (message is Watch watch)
            {
                if (watch.Watchee.Equals(this) && !watch.Watcher.Equals(this))
                {
                    watch.Watcher.SendSystemMessage(new DeathWatchNotification(watch.Watchee, existenceConfirmed: false, addressTerminated: false));
                }
                return(true);
            }
            if (message is Unwatch)
            {
                return(true);    //Just ignore
            }
            if (message is Identify identify)
            {
                sender.Tell(new ActorIdentity(identify.MessageId, null));
                return(true);
            }

            if (message is ActorSelectionMessage actorSelectionMessage)
            {
                if (actorSelectionMessage.Message is Identify selectionIdentify)
                {
                    if (!actorSelectionMessage.WildCardFanOut)
                    {
                        sender.Tell(new ActorIdentity(selectionIdentify.MessageId, null));
                    }
                }
                else
                {
                    if (actorSelectionMessage.Message is IDeadLetterSuppression selectionDeadLetterSuppression)
                    {
                        PublishSupressedDeadLetter(selectionDeadLetterSuppression, sender);
                    }
                    else
                    {
                        _eventStream.Publish(new DeadLetter(actorSelectionMessage.Message, sender.IsNobody() ? _provider.DeadLetters : sender, this));
                    }
                }
                return(true);
            }

            if (message is IDeadLetterSuppression deadLetterSuppression)
            {
                PublishSupressedDeadLetter(deadLetterSuppression, sender);
                return(true);
            }

            return(false);
        }
Пример #18
0
        protected override void Load(ContainerBuilder builder)
        {
            //TODO: Expose and register this as appart of configuration system
            ActorAssemblyDefinitionConfiguration actorAssemblyConfig = new ActorAssemblyDefinitionConfiguration(Array.Empty <string>());

            foreach (var s in actorAssemblyConfig.AssemblyNames)
            {
                Debug.Log($"Actor Assembly: {s}");
            }

            Debug.Log(AppDomain.CurrentDomain.GetAssemblies().Aggregate("Loaded Assemblies: ", (s, assembly) => $"{s} {assembly.GetName().Name}"));

            //The below loads the actor assemblies defined in the configuration.
            //It then searches for all message handlers and then registers them.
            //It's a complicated process.
            //TODO: Support actually loading unloaded assemblies (like 3rd party user assemblies)
            foreach (Assembly actorAssemblyToParse in actorAssemblyConfig.AssemblyNames
                     .Select(d => AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => d == a.GetName().Name.ToLower()))
                     .Where(a => a != null))
            {
                Debug.Log($"Parsing ActorAssembly: {actorAssemblyToParse.GetName().Name}");
                foreach (Type t in actorAssemblyToParse.GetTypes())
                {
                    //If they have the handler attribute, we should just register it.
                    if (t.GetCustomAttributes <EntityActorMessageHandlerAttribute>().Any())
                    {
                        Debug.Log($"Register ActorMessageHandler: {t.Name}");

                        //Now we need to find the actor state type
                        Type actorStateType = t.GetInterfaces()
                                              .First(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEntityActorMessageHandler <,>))
                                              .GenericTypeArguments.First();

                        var handlerRegisteration = builder.RegisterType(t)
                                                   .AsSelf()
                                                   .As(typeof(IEntityActorMessageHandler <,>).MakeGenericType(new Type[2] {
                            actorStateType, typeof(EntityActorMessage)
                        }))
                                                   .As <IEntityActorMessageHandler>()
                                                   .SingleInstance();

                        foreach (var attri in t.GetCustomAttributes <EntityActorMessageHandlerAttribute>())
                        {
                            //TODO: Support multiple level inherited types.
                            //If the actor has a different state type we should assume it's valid if it can be assigned.
                            Type specificActorStateType = attri.TargetActorType.BaseType.GenericTypeArguments.Reverse().First();

                            if (specificActorStateType != actorStateType)
                            {
                                if (actorStateType.IsAssignableFrom(specificActorStateType))
                                {
                                    handlerRegisteration = handlerRegisteration
                                                           .As(typeof(IEntityActorMessageHandler <,>).MakeGenericType(new Type[2] {
                                        specificActorStateType, typeof(EntityActorMessage)
                                    }));
                                }
                                else
                                {
                                    throw new InvalidOperationException($"Actor: {attri.TargetActorType.Name} attempted to use Handler: {t.Name} but had non-matching state Types: {actorStateType.Name}/{specificActorStateType.Name}");
                                }
                            }
                        }
                    }
                    else if (typeof(IEntityActor).IsAssignableFrom(t))
                    {
                        //Don't want to register abstract entities.
                        if (!t.IsAbstract)
                        {
                            Debug.Log($"Register Actor: {t.Name}");
                            builder.RegisterType(t)
                            .AsSelf();
                        }
                    }
                }
            }

            //Below is an open generic registeration of the generic router
            //this makes it EASY to inject into the actors
            builder.RegisterGeneric(typeof(ReflectionBasedGenericMessageRouter <,>))
            .As(typeof(IEntityActorMessageRouteable <,>))
            .SingleInstance();

            //Create the root of the actor system.
            builder.RegisterInstance(ActorSystem.Create("Root"))
            .AsSelf()
            .As <ActorSystem>()
            .As <IActorRefFactory>()
            .SingleInstance();

            builder.Register <IScheduler>(context =>
            {
                ActorSystem actorSystem = context.Resolve <ActorSystem>();

                return(actorSystem.Scheduler);
            })
            .As <IScheduler>()
            .SingleInstance();

            //Creates the autofac dependency resolver that can be used to actually resolve
            //the Actor's dependencies.
            builder.Register(context =>
            {
                if (!context.IsRegistered <IEntityActorMessageRouteable <DefaultWorldActor, WorldActorState> >())
                {
                    Debug.LogError($"CRITICAL dependency for Actor IOC not registered.");
                }

                if (!context.IsRegistered <DefaultWorldActor>())
                {
                    Debug.LogError($"CRITICAL dependency for Actor IOC not registered.");
                }

                return(new AutoFacDependencyResolver(context.Resolve <ILifetimeScope>(), context.Resolve <ActorSystem>()));
            })
            .As <IDependencyResolver>()
            .AsSelf()
            .SingleInstance();

            builder.RegisterType <DefaultWorldActor>()
            .AsSelf();

            builder.RegisterType <UnityAkkaActorLoggerAdapter>()
            .AsSelf()
            .As <ILoggingAdapter>()
            .SingleInstance();

            builder.RegisterType <UnityLoggerActor>()
            .AsSelf();

            builder.RegisterType <DefaultGameObjectEntityActorFactory>()
            .As <IGameObjectEntityActorFactory>()
            .SingleInstance();

            //This creates the World actor.
            builder.Register(context =>
            {
                try
                {
                    IDependencyResolver resolver = context.Resolve <IDependencyResolver>();
                    ActorSystem actorSystem      = context.Resolve <ActorSystem>();
                    actorSystem.ActorOf(resolver.Create <UnityLoggerActor>(), "Logger");
                    IActorRef worldActorReference = actorSystem.ActorOf(resolver.Create <DefaultWorldActor>(), "World");

                    if (worldActorReference.IsNobody())
                    {
                        Debug.LogError($"FAILED TO CREATE WORLD ACTOR.");
                    }

                    return(new WorldActorReferenceAdapter(worldActorReference));
                }
                catch (Exception e)
                {
                    Debug.LogError($"Failed to create WorldActor in IoC. Reason: {e.Message}\n\nStack: {e.StackTrace}");
                    throw;
                }
            })
            .As <IWorldActorRef>()
            .SingleInstance();
        }