/// <summary>
 /// Initializes a new instance of the <see cref="TailChoppingRoutee"/> class.
 /// </summary>
 /// <param name="routees">The list of routees that the router uses to send messages.</param>
 /// <param name="within">The time within which at least one response is expected.</param>
 /// <param name="interval">The duration after which the next routee will be picked.</param>
 /// <param name="scheduler">The <see cref="IScheduler"/> used to force deadlines.</param>
 public TailChoppingRoutee(Routee[] routees, TimeSpan within, TimeSpan interval, IScheduler scheduler)
 {
     _routees = routees;
     _within = within;
     _interval = interval;
     _scheduler = scheduler;
 }
Пример #2
0
        private Routee SelectNext(Routee[] routees)
        {
            var winningScore = long.MaxValue;

            // round robin fallback
            var winner = routees[(Interlocked.Increment(ref _next) & int.MaxValue) %  routees.Length];

            for (int i = 0; i < routees.Length; i++)
            {
                var routee = routees[i];
                var cell = TryGetActorCell(routee);
                if (cell != null)
                {
                    // routee can be reasoned about it's mailbox size
                    var score = cell.NumberOfMessages;
                    if (score == 0)
                    {
                        // no messages => instant win    
                        return routee;
                    }

                    if (winningScore > score)
                    {
                        winningScore = score;
                        winner = routee;
                    }
                }
            }

            return winner;
        }
 /// <summary>
 /// Selects all routees and creates a TailChoppingRoutee.
 /// </summary>
 /// <param name="message">The message to use.</param>
 /// <param name="routees">The routees to select from.</param>
 /// <returns>A TailChoppingRoutee to handle the tail chopping routing.</returns>
 public override Routee Select(object message, Routee[] routees)
 {
     if(routees.IsNullOrEmpty())
     {
         return Routee.NoRoutee;
     }
     return new TailChoppingRoutee(routees, _within, _interval, _scheduler);
 }
Пример #4
0
 /// <summary>
 /// Selects the routee for the given message.
 /// </summary>
 /// <param name="message">The message.</param>
 /// <param name="routees">The routees.</param>
 /// <returns>Routee.</returns>
 public override Routee Select(object message, Routee[] routees)
 {
     if (routees == null || routees.Length == 0)
     {
         return Routee.NoRoutee;
     }
     return routees[rnd.Next(routees.Length - 1)%routees.Length];
 }
Пример #5
0
 /// <summary>
 /// Selects the routee for the given message.
 /// </summary>
 /// <param name="message">The message.</param>
 /// <param name="routees">The routees.</param>
 /// <returns>Routee.</returns>
 public override Routee Select(object message, Routee[] routees)
 {
     if (routees == null || routees.Length == 0)
     {
         return Routee.NoRoutee;
     }
     return routees[ThreadLocalRandom.Current.Next(routees.Length - 1)%routees.Length];
 }
 public override Routee Select(object message, Routee[] routees)
 {
     if (routees == null || routees.Length == 0)
     {
         return Routee.NoRoutee;
     }
     return new ScatterGatherFirstCompletedRoutees(routees,_within);
 }
Пример #7
0
 /// <summary>
 /// Picks the next <see cref="Routee"/> in the collection to receive the <paramref name="message"/>.
 /// </summary>
 /// <param name="message">The message that is being routed.</param>
 /// <param name="routees">A collection of routees to choose from when receiving the <paramref name="message"/>.</param>
 /// <returns>A <see cref="Routee" /> that is receives the <paramref name="message"/>.</returns>
 public override Routee Select(object message, Routee[] routees)
 {
     if (routees == null || routees.Length == 0)
     {
         return Routee.NoRoutee;
     }
     return routees[(Interlocked.Increment(ref _next) & int.MaxValue) % routees.Length];
 }
Пример #8
0
        public override Routee Select(object message, Routee[] routees)
        {
            if (message is ConsistentHashable)
            {
                var hashable = (ConsistentHashable) message;
                int hash = hashable.ConsistentHashKey.GetHashCode();
                return routees[hash%routees.Length];
            }

            throw new NotSupportedException("Only ConsistentHashable messages are supported right now");
        }
Пример #9
0
 private void AddRoutees(Routee[] routees)
 {
     foreach (var routee in routees)
     {
         if (routee is ActorRefRoutee)
         {
             var @ref = ((ActorRefRoutee)routee).Actor;
             Watch(@ref);
         }
     }
     Router = Router.WithRoutees(routees);
 }
Пример #10
0
 protected void AddRoutees(Routee[] routees)
 {
     foreach(var routee in routees)
     {
         if(routee is ActorRefRoutee)
         {
             var @ref = ((ActorRefRoutee)routee).Actor;
             Watch(@ref);
         }
     }
     _router = _router.WithRoutees(_router.Routees.Concat(routees).ToArray());
 }
Пример #11
0
 private ICell TryGetActorCell(Routee routee)
 {
     var refRoutee = routee as ActorRefRoutee;
     if (refRoutee != null)
     {
         var actorRef = refRoutee.Actor as ActorRefWithCell;
         if (actorRef != null)
         {
             return actorRef.Underlying;
         }
     }
     return null;
 }
Пример #12
0
 /// <summary>
 /// Picks the next <see cref="Routee"/> in the collection to receive the <paramref name="message"/>.
 /// </summary>
 /// <param name="message">The message that is being routed.</param>
 /// <param name="routees">A collection of routees to choose from when receiving the <paramref name="message"/>.</param>
 /// <returns>A <see cref="Routee" /> that is receives the <paramref name="message"/>.</returns>
 public override Routee Select(object message, Routee[] routees)
 {
     if (routees.Length > 0)
     {
         var size = routees.Length;
         int index = (Interlocked.Increment(ref _next) & int.MaxValue)%size;
         return routees[index < 0 ? size + index - 1 : index];
     }
     else
     {
         return Routee.NoRoutee;
     }
 }
Пример #13
0
        public void DefaultResizer_must_use_settings_to_evaluate_capacity()
        {
            var resizer = new DefaultResizer(2, 3);
            var c1 = resizer.Capacity(new Routee[] { });
            c1.ShouldBe(2);

            var current = new Routee[]
            {
                new ActorRefRoutee(Sys.ActorOf<ResizerTestActor>()),
                new ActorRefRoutee(Sys.ActorOf<ResizerTestActor>())
            };
            var c2 = resizer.Capacity(current);
            c2.ShouldBe(0);
        }
Пример #14
0
 public override string ToString()
 {
     if (Routee is ActorRefRoutee)
     {
         var actorRef = Routee as ActorRefRoutee;
         return(ToStringWithFullAddress(actorRef.Actor.Path));
     }
     else if (Routee is ActorSelectionRoutee)
     {
         var selection = Routee as ActorSelectionRoutee;
         return(ToStringWithFullAddress(selection.Selection.Anchor.Path) + selection.Selection.PathString);
     }
     else
     {
         return(Routee.ToString());
     }
 }
Пример #15
0
        /// <summary>
        /// Used to stop child routees - typically used in resizable <see cref="Pool"/> routers
        /// </summary>
        /// <param name="routee">TBD</param>
        private void StopIfChild(Routee routee)
        {
            var         actorRefRoutee = routee as ActorRefRoutee;
            IChildStats childActorStats;

            if (actorRefRoutee != null && TryGetChildStatsByName(actorRefRoutee.Actor.Path.Name, out childActorStats))
            {
                var childRef = childActorStats as ChildRestartStats;
                if (childRef != null && childRef.Child != null)
                {
                    // The reason for the delay is to give concurrent
                    // messages a chance to be placed in mailbox before sending PoisonPill,
                    // best effort.
                    System.Scheduler.ScheduleTellOnce(TimeSpan.FromMilliseconds(100), actorRefRoutee.Actor,
                                                      PoisonPill.Instance, Self);
                }
            }
        }
Пример #16
0
        public Router(RoutingLogic logic, IActorRef routee, params IActorRef[] routees)
        {
            if (routees == null || routees.Length == 0)
            {
                _routees = new [] { Routee.FromActorRef(routee) };
            }
            else
            {
                var routeesLength = routees.Length;

                //Convert and put routee first in a new array
                _routees    = new Routee[routeesLength + 1];
                _routees[0] = Routee.FromActorRef(routee);

                //Convert all routees and put them into the new array
                for (var i = 0; i < routees.Length; i++)
                {
                    var actorRef = routees[i];
                    var r        = Routee.FromActorRef(actorRef);
                    _routees[i + 1] = r;
                }
            }
            RoutingLogic = logic;
        }
Пример #17
0
 public Router AddRoutee(Routee routee)
 {
     return new Router(logic, routees.Add(routee));
 }
Пример #18
0
        /// <summary>
        /// Create a new instance without the specified routee.
        /// </summary>
        public Router RemoveRoutee(Routee routee)
        {
            var routees = _routees.Where(r => !r.Equals(routee)).ToArray();

            return(new Router(_logic, routees));
        }
Пример #19
0
 protected virtual void Send(Routee routee, object message, IActorRef sender)
 {
     routee.Send(UnWrap(message), sender);
 }
Пример #20
0
        /// <summary>
        /// Picks a <see cref="Routee" /> to receive the <paramref name="message" />.
        /// </summary>
        /// <param name="message">The message that is being routed</param>
        /// <param name="routees">A collection of routees to choose from when receiving the <paramref name="message" />.</param>
        /// <returns>A <see cref="Routee" /> that receives the <paramref name="message" />.</returns>
        public override Routee Select(object message, Routee[] routees)
        {
            if (message == null || routees == null || routees.Length == 0)
                return Routee.NoRoutee;

            Func<ConsistentHash<ConsistentRoutee>> updateConsistentHash = () =>
            {
                // update consistentHash when routees are changed
                // changes to routees are rare when no changes this is a quick operation
                var oldConsistHashTuple = _consistentHashRef.Value;
                var oldRoutees = oldConsistHashTuple.Item1;
                var oldConsistentHash = oldConsistHashTuple.Item2;

                if (oldRoutees == null || !routees.SequenceEqual(oldRoutees))
                {
                    // when other instance, same content, no need to re-hash, but try to set routees
                    var consistentHash = routees == oldRoutees
                        ? oldConsistentHash
                        : ConsistentHash.Create(routees.Select(x => new ConsistentRoutee(x, _selfAddress)), _vnodes);
                    //ignore, don't update, in case of CAS failure
                    _consistentHashRef.CompareAndSet(oldConsistHashTuple, Tuple.Create(routees, consistentHash));
                    return consistentHash;
                }
                return oldConsistentHash;
            };

            Func<object, Routee> target = hashData =>
            {
                try
                {
                    var currentConsistentHash = updateConsistentHash();
                    if (currentConsistentHash.IsEmpty) return Routee.NoRoutee;
                    else
                    {
                        if (hashData is byte[])
                            return currentConsistentHash.NodeFor(hashData as byte[]).Routee;
                        if (hashData is string)
                            return currentConsistentHash.NodeFor(hashData as string).Routee;
                        return
                            currentConsistentHash.NodeFor(
                                _system.Serialization.FindSerializerFor(hashData).ToBinary(hashData)).Routee;
                    }
                }
                catch (Exception ex)
                {
                    //serialization failed
                    _log.Value.Warning("Couldn't route message with consistent hash key [{0}] due to [{1}]", hashData,
                        ex.Message);
                    return Routee.NoRoutee;
                }
            };

            if (_hashMapping(message) != null)
            {
                return target(ConsistentHash.ToBytesOrObject(_hashMapping(message)));
            }
            else if (message is IConsistentHashable)
            {
                var hashable = (IConsistentHashable) message;
                return target(ConsistentHash.ToBytesOrObject(hashable.ConsistentHashKey));
            }
            else
            {
                _log.Value.Warning("Message [{0}] must be handled by hashMapping, or implement [{1}] or be wrapped in [{2}]",
                    message.GetType().Name, typeof (IConsistentHashable).Name, typeof (ConsistentHashableEnvelope).Name);
                return Routee.NoRoutee;
            }
        }
Пример #21
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AddRoutee"/> class.
 /// </summary>
 /// <param name="routee">The routee added to the router's collection of routees.</param>
 public AddRoutee(Routee routee)
 {
     Routee = routee;
 }
 public ScatterGatherFirstCompletedRoutees(Routee[] routees, TimeSpan within)
 {
     _routees = routees;
     _within = within;
 }
Пример #23
0
 private Routee[] Include(Routee routee)
 {
     return(routees.Union(Enumerable.Repeat(routee, 1)).ToArray());
 }
Пример #24
0
 /// <summary>
 /// TBD
 /// </summary>
 /// <param name="routee">TBD</param>
 internal void AddRoutee(Routee routee)
 {
     AddRoutees(new[] { routee });
 }
Пример #25
0
 /// <summary>
 /// Picks a <see cref="Routee" /> to receive the <paramref name="message" />.
 /// </summary>
 /// <param name="message">The message that is being routed</param>
 /// <param name="routees">A collection of routees to choose from when receiving the <paramref name="message" />.</param>
 /// <returns>A <see cref="Routee" /> that receives the <paramref name="message" />.</returns>
 public override Routee Select(object message, Routee[] routees)
 {
     return routees == null || routees.Length == 0
         ? Routee.NoRoutee
         : SelectNext(routees);
 }
Пример #26
0
 internal void RemoveRoutee(Routee routee, bool stopChild)
 {
     RemoveRoutees(new List<Routee>() { routee }, stopChild);
 }
 /// <summary>
 /// Picks all the provided <paramref name="routees"/> to receive the <paramref name="message" />.
 /// </summary>
 /// <param name="message">The message that is being routed</param>
 /// <param name="routees">A collection of routees to choose from when receiving the <paramref name="message" />.</param>
 /// <returns>A <see cref="ScatterGatherFirstCompletedRoutees" /> that receives the <paramref name="message" />.</returns>
 public override Routee Select(object message, Routee[] routees)
 {
     return new ScatterGatherFirstCompletedRoutees(routees,_within);
 }
Пример #28
0
 public abstract Routee Select(object message, Routee[] routees);
Пример #29
0
 public SeveralRoutees(Routee[] routees)
 {
     this.routees = routees;
 }
Пример #30
0
 private void Unwatch(Routee routee)
 {
     var actorRef = routee as ActorRefRoutee;
     if (actorRef != null) Unwatch(actorRef.Actor);
 }
Пример #31
0
 public ConsistentRoutee(Routee routee, Address selfAddress)
 {
     SelfAddress = selfAddress;
     Routee      = routee;
 }
Пример #32
0
 /// <summary>
 /// Create a new instance with one more routee and the same <see cref="RoutingLogic"/>.
 /// </summary>
 /// <param name="routee">The routee to add.</param>
 /// <returns>A new <see cref="Router"/> instance with this routee added.</returns>
 public virtual Router AddRoutee(Routee routee)
 {
     return(new Router(RoutingLogic, _routees.Union(new[] { routee }).ToArray()));
 }
Пример #33
0
 public Router AddRoutee(Routee routee)
 {
     return(new Router(logic, Include(routee)));
 }
Пример #34
0
 /// <summary>
 /// Initializes a new instance of the <see cref="RemoveRoutee"/> class.
 /// </summary>
 /// <param name="routee">The routee to remove from the router's collection of routees.</param>
 public RemoveRoutee(Routee routee)
 {
     Routee = routee;
 }
Пример #35
0
 public override Routee Select(object message, Routee[] routees)
 {
     if (routees == null || !routees.Any())
         return Routee.NoRoutee;
     return new SeveralRoutees(routees);
 }
Пример #36
0
 public Router AddRoutee(Routee routee)
 {
     return(new Router(logic, routees.Add(routee)));
 }
Пример #37
0
 /// <summary>
 /// Initializes a new instance of the <see cref="RemoveRoutee"/> class.
 /// </summary>
 /// <param name="routee">The routee to remove from the router's collection of routees.</param>
 public RemoveRoutee(Routee routee)
 {
     Routee = routee;
 }
Пример #38
0
 public virtual void Send(Routee routee, object message, ActorRef sender)
 {
     routee.Send(UnWrap(message), sender);
 }
Пример #39
0
 public ConsistentRoutee(Routee routee, Address selfAddress)
 {
     SelfAddress = selfAddress;
     Routee = routee;
 }
Пример #40
0
 /// <summary>
 /// Used to stop child routees - typically used in resizable <see cref="Pool"/> routers
 /// </summary>
 /// <param name="routee"></param>
 private void StopIfChild(Routee routee)
 {
     var actorRefRoutee = routee as ActorRefRoutee;
     IChildStats childActorStats;
     if (actorRefRoutee != null && TryGetChildStatsByName(actorRefRoutee.Actor.Path.Name, out childActorStats))
     {
         var childRef = childActorStats as ChildRestartStats;
         if (childRef != null && childRef.Child != null)
         {
             // The reason for the delay is to give concurrent
             // messages a chance to be placed in mailbox before sending PoisonPill,
             // best effort.
             System.Scheduler.ScheduleTellOnce(TimeSpan.FromMilliseconds(100), actorRefRoutee.Actor,
                 PoisonPill.Instance, Self);
         }
     }
 }
Пример #41
0
 /// <summary>
 /// Create a new instance with one more routee and the same <see cref="RoutingLogic"/>.
 /// </summary>
 public Router AddRoutee(Routee routee)
 {
     return(new Router(_logic, _routees.Union(new[] { routee }).ToArray()));
 }
Пример #42
0
 internal void AddRoutee(Routee routee)
 {
     AddRoutees(new[] { routee });
 }
Пример #43
0
 internal void RemoveRoutee(Routee routee, bool stopChild)
 {
     RemoveRoutees(new[] { routee }, stopChild);
 }
Пример #44
0
 public virtual void Send(Routee routee, object message, ActorRef sender)
 {
     routee.Send(UnWrap(message), sender);
 }
Пример #45
0
 /// <summary>
 /// TBD
 /// </summary>
 /// <param name="routee">TBD</param>
 /// <param name="stopChild">TBD</param>
 internal void RemoveRoutee(Routee routee, bool stopChild)
 {
     RemoveRoutees(new[] { routee }, stopChild);
 }
Пример #46
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AddRoutee"/> class.
 /// </summary>
 /// <param name="routee">The routee added to the router's collection of routees.</param>
 public AddRoutee(Routee routee)
 {
     Routee = routee;
 }