/// <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; }
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); }
/// <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]; }
/// <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); }
/// <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]; }
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"); }
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); }
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()); }
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; }
/// <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; } }
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); }
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()); } }
/// <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); } } }
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; }
public Router AddRoutee(Routee routee) { return new Router(logic, routees.Add(routee)); }
/// <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)); }
protected virtual void Send(Routee routee, object message, IActorRef sender) { routee.Send(UnWrap(message), sender); }
/// <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; } }
/// <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; }
private Routee[] Include(Routee routee) { return(routees.Union(Enumerable.Repeat(routee, 1)).ToArray()); }
/// <summary> /// TBD /// </summary> /// <param name="routee">TBD</param> internal void AddRoutee(Routee routee) { AddRoutees(new[] { routee }); }
/// <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); }
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); }
public abstract Routee Select(object message, Routee[] routees);
public SeveralRoutees(Routee[] routees) { this.routees = routees; }
private void Unwatch(Routee routee) { var actorRef = routee as ActorRefRoutee; if (actorRef != null) Unwatch(actorRef.Actor); }
public ConsistentRoutee(Routee routee, Address selfAddress) { SelfAddress = selfAddress; Routee = routee; }
/// <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())); }
public Router AddRoutee(Routee routee) { return(new Router(logic, Include(routee))); }
/// <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; }
public override Routee Select(object message, Routee[] routees) { if (routees == null || !routees.Any()) return Routee.NoRoutee; return new SeveralRoutees(routees); }
public Router AddRoutee(Routee routee) { return(new Router(logic, routees.Add(routee))); }
public virtual void Send(Routee routee, object message, ActorRef sender) { routee.Send(UnWrap(message), sender); }
/// <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); } } }
/// <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())); }
internal void AddRoutee(Routee routee) { AddRoutees(new[] { routee }); }
internal void RemoveRoutee(Routee routee, bool stopChild) { RemoveRoutees(new[] { routee }, stopChild); }
/// <summary> /// TBD /// </summary> /// <param name="routee">TBD</param> /// <param name="stopChild">TBD</param> internal void RemoveRoutee(Routee routee, bool stopChild) { RemoveRoutees(new[] { routee }, stopChild); }