Inheritance: Akka.Actor.MinimalActorRef
Exemplo n.º 1
0
        /// <summary>
        /// INTERNAL API
        /// Convenience method used by remoting when receiving <see cref="ActorSelectionMessage" /> from a remote
        /// actor.
        /// </summary>
        /// <param name="anchor">TBD</param>
        /// <param name="sender">TBD</param>
        /// <param name="sel">TBD</param>
        internal static void DeliverSelection(IInternalActorRef anchor, IActorRef sender, ActorSelectionMessage sel)
        {
            if (sel.Elements.IsNullOrEmpty())
            {
                anchor.Tell(sel.Message, sender);
            }
            else
            {
                var iter = sel.Elements.Iterator();

                Action <IInternalActorRef> rec = null;
                rec = @ref => @ref.Match()
                      .With <ActorRefWithCell>(refWithCell =>
                {
                    var emptyRef = new EmptyLocalActorRef(refWithCell.Provider, anchor.Path / sel.Elements.Select(el => el.ToString()), refWithCell.Underlying.System.EventStream);

                    iter.Next()
                    .Match()
                    .With <SelectParent>(_ =>
                    {
                        var parent = @ref.Parent;
                        if (iter.IsEmpty())
                        {
                            parent.Tell(sel.Message, sender);
                        }
                        else
                        {
                            rec(parent);
                        }
                    })
                    .With <SelectChildName>(name =>
                    {
                        var child = refWithCell.GetSingleChild(name.Name);
                        if (child is Nobody)
                        {
                            // don't send to emptyRef after wildcard fan-out
                            if (!sel.WildCardFanOut)
                            {
                                emptyRef.Tell(sel, sender);
                            }
                        }
                        else if (iter.IsEmpty())
                        {
                            child.Tell(sel.Message, sender);
                        }
                        else
                        {
                            rec(child);
                        }
                    })
                    .With <SelectChildPattern>(p =>
                    {
                        // fan-out when there is a wildcard
                        var children         = refWithCell.Children;
                        var matchingChildren = children
                                               .Where(c => c.Path.Name.Like(p.PatternStr))
                                               .ToList();

                        if (iter.IsEmpty())
                        {
                            if (matchingChildren.Count == 0 && !sel.WildCardFanOut)
                            {
                                emptyRef.Tell(sel, sender);
                            }
                            else
                            {
                                matchingChildren.ForEach(child => child.Tell(sel.Message, sender));
                            }
                        }
                        else
                        {
                            // don't send to emptyRef after wildcard fan-out
                            if (matchingChildren.Count == 0 && !sel.WildCardFanOut)
                            {
                                emptyRef.Tell(sel, sender);
                            }
                            else
                            {
                                var m = new ActorSelectionMessage(sel.Message, iter.ToVector().ToArray(),
                                                                  sel.WildCardFanOut || matchingChildren.Count > 1);
                                matchingChildren.ForEach(child => DeliverSelection(child as IInternalActorRef, sender, m));
                            }
                        }
                    });
                })
                      // foreign ref, continue by sending ActorSelectionMessage to it with remaining elements
                      .Default(_ => @ref.Tell(new ActorSelectionMessage(sel.Message, iter.ToVector().ToArray()), sender));

                rec(anchor);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// INTERNAL API
        /// Convenience method used by remoting when receiving <see cref="ActorSelectionMessage" /> from a remote
        /// actor.
        /// </summary>
        /// <param name="anchor">TBD</param>
        /// <param name="sender">TBD</param>
        /// <param name="sel">TBD</param>
        internal static void DeliverSelection(IInternalActorRef anchor, IActorRef sender, ActorSelectionMessage sel)
        {
            if (sel.Elements.IsNullOrEmpty())
            {
                anchor.Tell(sel.Message, sender);
            }
            else
            {
                var iter = sel.Elements.Iterator();

                void Rec(IInternalActorRef actorRef)
                {
                    if (actorRef is ActorRefWithCell refWithCell)
                    {
                        var emptyRef = new EmptyLocalActorRef(
                            provider: refWithCell.Provider,
                            path: anchor.Path / sel.Elements.Select(el => el.ToString()),
                            eventStream: refWithCell.Underlying.System.EventStream);

                        switch (iter.Next())
                        {
                        case SelectParent _:
                            var parent = actorRef.Parent;

                            if (iter.IsEmpty())
                            {
                                parent.Tell(sel.Message, sender);
                            }
                            else
                            {
                                Rec(parent);
                            }

                            break;

                        case SelectChildName name:
                            var child = refWithCell.GetSingleChild(name.Name);

                            if (child is Nobody)
                            {
                                // don't send to emptyRef after wildcard fan-out
                                if (!sel.WildCardFanOut)
                                {
                                    emptyRef.Tell(sel, sender);
                                }
                            }
                            else if (iter.IsEmpty())
                            {
                                child.Tell(sel.Message, sender);
                            }
                            else
                            {
                                Rec(child);
                            }

                            break;

                        case SelectChildPattern pattern:
                            // fan-out when there is a wildcard
                            var matchingChildren = refWithCell.Children
                                                   .Where(c => c.Path.Name.Like(pattern.PatternStr))
                                                   .ToList();

                            if (iter.IsEmpty())
                            {
                                if (matchingChildren.Count == 0 && !sel.WildCardFanOut)
                                {
                                    emptyRef.Tell(sel, sender);
                                }
                                else
                                {
                                    for (var i = 0; i < matchingChildren.Count; i++)
                                    {
                                        matchingChildren[i].Tell(sel.Message, sender);
                                    }
                                }
                            }
                            else
                            {
                                // don't send to emptyRef after wildcard fan-out
                                if (matchingChildren.Count == 0 && !sel.WildCardFanOut)
                                {
                                    emptyRef.Tell(sel, sender);
                                }
                                else
                                {
                                    var message = new ActorSelectionMessage(
                                        message: sel.Message,
                                        elements: iter.ToVector().ToArray(),
                                        wildCardFanOut: sel.WildCardFanOut || matchingChildren.Count > 1);

                                    for (var i = 0; i < matchingChildren.Count; i++)
                                    {
                                        DeliverSelection(matchingChildren[i] as IInternalActorRef, sender, message);
                                    }
                                }
                            }
                            break;
                        }
                    }
                    else
                    {
                        // foreign ref, continue by sending ActorSelectionMessage to it with remaining elements
                        actorRef.Tell(new ActorSelectionMessage(sel.Message, iter.ToVector().ToArray()), sender);
                    }
                }

                Rec(anchor);
            }
        }
Exemplo n.º 3
0
        public void Select_WithClient_should_update_Client_and_copy_the_rest_of_the_properties_BUG_427()
        {
            var deadline = new TimeSpan(Sys.Scheduler.MonotonicClock.Ticks/2); //Some point in the past
            Predicate<object> predicate = o => true;
            var actorRef = new EmptyLocalActorRef(((ActorSystemImpl)Sys).Provider, new RootActorPath(new Address("akka", "test")), Sys.EventStream);
            var select = new Select(deadline, predicate, actorRef);

            var updatedActorRef = new EmptyLocalActorRef(((ActorSystemImpl)Sys).Provider, new RootActorPath(new Address("akka2", "test2")), Sys.EventStream);

            var updatedSelect = (Select)select.WithClient(updatedActorRef);
            updatedSelect.Deadline.ShouldBe(deadline);
            updatedSelect.Predicate.ShouldBe(predicate);
            updatedSelect.Client.ShouldBe(updatedActorRef);
        }
Exemplo n.º 4
0
        /// <summary>
        ///     INTERNAL API
        ///     Convenience method used by remoting when receiving <see cref="ActorSelectionMessage" /> from a remote
        ///     actor.
        /// </summary>
        internal static void DeliverSelection(IInternalActorRef anchor, IActorRef sender, ActorSelectionMessage sel)
        {
            if (sel.Elements.IsNullOrEmpty())
            {
                anchor.Tell(sel.Message, sender);
            }
            else
            {
                var iter = sel.Elements.Iterator();

                Action<IInternalActorRef> rec = null;
                rec = @ref => @ref.Match()
                    .With<ActorRefWithCell>(refWithCell =>
                    {
                        var emptyRef = new EmptyLocalActorRef(refWithCell.Provider, anchor.Path/sel.Elements.Select(el => el.ToString()), refWithCell.Underlying.System.EventStream);

                        iter.Next()
                            .Match()
                            .With<SelectParent>(_ =>
                            {
                                var parent = @ref.Parent;
                                if (iter.IsEmpty())
                                    parent.Tell(sel.Message, sender);
                                else
                                    rec(parent);
                            })
                            .With<SelectChildName>(name =>
                            {
                                var child = refWithCell.GetSingleChild(name.Name);
                                if (child is Nobody)
                                {
                                    if (!sel.WildCardFanOut) 
                                        emptyRef.Tell(sel, sender);
                                }
                                else if (iter.IsEmpty())
                                {
                                    child.Tell(sel.Message, sender);
                                }
                                else
                                {
                                    rec(child);
                                }

                            })
                            .With<SelectChildPattern>(p =>
                            {
                                var children = refWithCell.Children;
                                var matchingChildren = children
                                    .Where(c => c.Path.Name.Like(p.PatternStr))
                                    .ToList();

                                if (iter.IsEmpty())
                                {
                                    if(matchingChildren.Count ==0 && !sel.WildCardFanOut)
                                        emptyRef.Tell(sel, sender);
                                    else
                                        matchingChildren.ForEach(child => child.Tell(sel.Message, sender));
                                }
                                else
                                {
                                    if (matchingChildren.Count == 0 && !sel.WildCardFanOut)
                                        emptyRef.Tell(sel, sender);
                                    else
                                    {
                                        var m = new ActorSelectionMessage(sel.Message, iter.ToVector().ToArray(), 
                                            sel.WildCardFanOut || matchingChildren.Count > 1);
                                        matchingChildren.ForEach(child => DeliverSelection(child as IInternalActorRef, sender, m));
                                    }
                                }
                            });
                    })
                    .Default(_ => @ref.Tell(new ActorSelectionMessage(sel.Message, iter.ToVector().ToArray()), sender));

                rec(anchor);
            }
        }
Exemplo n.º 5
0
        public void Select_WithClient_should_update_Client_and_copy_the_rest_of_the_properties_BUG_427()
        {
            var deadline = new DateTime(1919, 5, 24);
            Predicate<object> predicate = o => true;
            var actorRef = new EmptyLocalActorRef(((ActorSystemImpl)Sys).Provider, new RootActorPath(new Address("akka", "test")), Sys.EventStream);
            var select = new Select(deadline, predicate, actorRef);

            var updatedActorRef = new EmptyLocalActorRef(((ActorSystemImpl)Sys).Provider, new RootActorPath(new Address("akka2", "test2")), Sys.EventStream);

            var updatedSelect = (Select)select.WithClient(updatedActorRef);
            updatedSelect.Deadline.ShouldBe(deadline);
            updatedSelect.Predicate.ShouldBe(predicate);
            updatedSelect.Client.ShouldBe(updatedActorRef);
        }