public override ActorRef GetChild(IEnumerable <string> name) { var current = (ActorRef)this; var index = 0; foreach (var element in name) { switch (element) { case "..": return(Parent.GetChild(name.Skip(index))); case "": break; default: var nameAndUid = ActorCell.SplitNameAndUid(element); ChildStats stats; if (Lookup.TryGetChildStatsByName(nameAndUid.Name, out stats)) { var crs = stats as ChildRestartStats; var uid = nameAndUid.Uid; if (crs != null && (uid == ActorCell.UndefinedUid || uid == crs.Uid)) { crs.Child.GetChild(name.Skip(index)); } } return(Nobody); } index++; } return(current); }
/// <summary> /// Processes the failure. /// </summary> /// <param name="actorCell">The actor cell.</param> /// <param name="restart">if set to <c>true</c> [restart].</param> /// <param name="child">The child.</param> /// <param name="cause">The cause.</param> private void ProcessFailure(ActorCell actorCell, bool restart, ActorRef child, Exception cause) { if (restart) { RestartChild(child, cause, false); } else { child.AsInstanceOf <InternalActorRef>().Stop(); } /* * if (children.nonEmpty) { * if (restart && children.forall(_.requestRestartPermission(retriesWindow))) * children foreach (crs ⇒ restartChild(crs.child, cause, suspendFirst = (crs.child != child))) * else * for (c ← children) context.stop(c.child) * } */ //if (children.Any()) //{ // if (restart) // { // } // else // { // foreach (var child in children) // { // child.Stop(); // } // } //} }
//This mimics what's done in Akka`s construction of an LocalActorRef. //The actorCell is created in the overridable newActorCell() during creation of the instance. //Since we don't want calls to virtual members in C# we must supply it. // //This is the code from Akka: // private[akka] class LocalActorRef private[akka] ( // _system: ActorSystemImpl, // _props: Props, // _dispatcher: MessageDispatcher, // _mailboxType: MailboxType, // _supervisor: InternalActorRef, // override val path: ActorPath) extends ActorRefWithCell with LocalRef { // private val actorCell: ActorCell = newActorCell(_system, this, _props, _dispatcher, _supervisor) // actorCell.init(sendSupervise = true, _mailboxType) // ... // } /// <summary> /// TBD /// </summary> /// <param name="system">TBD</param> /// <param name="props">TBD</param> /// <param name="dispatcher">TBD</param> /// <param name="mailboxType">TBD</param> /// <param name="supervisor">TBD</param> /// <param name="path">TBD</param> public LocalActorRef(ActorSystemImpl system, Props props, MessageDispatcher dispatcher, MailboxType mailboxType, IInternalActorRef supervisor, ActorPath path) { _system = system; _props = props; _dispatcher = dispatcher; MailboxType = mailboxType; _supervisor = supervisor; _path = path; /* * Safe publication of this class’s fields is guaranteed by Mailbox.SetActor() * which is called indirectly from ActorCell.init() (if you’re wondering why * this is at all important, remember that under the CLR readonly fields are only * frozen at the _end_ of the constructor, but we are publishing "this" before * that is reached). * This means that the result of NewActorCell needs to be written to the field * _cell before we call init and start, since we can start using "this" * object from another thread as soon as we run init. */ // ReSharper disable once VirtualMemberCallInConstructor _cell = NewActorCell(_system, this, _props, _dispatcher, _supervisor); // _cell needs to be assigned before Init is called. _cell.Init(true, MailboxType); }
protected virtual ActorCell NewCell() { var actorCell = new ActorCell(_system, this, _props, _dispatcher, _supervisor); actorCell.Init(sendSupervise: false, createMailbox: _createMailbox); return(actorCell); }
/// <summary></summary> /// <exception cref="InvalidOperationException"> /// This exception is thrown if the registering <paramref name="actor"/> is not the <see cref="_owner">owner</see>. /// </exception> internal override void Register(ActorCell actor) { var current = _owner; if(current != null && actor != current) throw new InvalidOperationException($"Cannot register to anyone but {_owner}"); _owner = actor; base.Register(actor); }
/// <summary> /// This is the main entry point: in case of a child’s failure, this method /// must try to handle the failure by resuming, restarting or stopping the /// child (and returning `true`), or it returns `false` to escalate the /// failure, which will lead to this actor re-throwing the exception which /// caused the failure. The exception will not be wrapped. /// This method calls <see cref="Akka.Actor.SupervisorStrategy"/>, which will /// log the failure unless it is escalated. You can customize the logging by /// setting <see cref="Akka.Actor.SupervisorStrategy" /> to `false` and /// do the logging inside the `decider` or override the `LogFailure` method. /// </summary> /// <param name="actorCell">The actor cell.</param> /// <param name="child">The child actor.</param> /// <param name="cause">The cause.</param> /// <param name="stats">The stats for the failed child.</param> /// <param name="children">TBD</param> /// <returns><c>true</c> if the child actor was handled, otherwise <c>false</c>.</returns> public bool HandleFailure(ActorCell actorCell, IActorRef child, Exception cause, ChildRestartStats stats, IReadOnlyCollection <ChildRestartStats> children) { var directive = Handle(child, cause); switch (directive) { case Directive.Escalate: LogFailure(actorCell, child, cause, directive); return(false); case Directive.Resume: LogFailure(actorCell, child, cause, directive); ResumeChild(child, cause); return(true); case Directive.Restart: LogFailure(actorCell, child, cause, directive); ProcessFailure(actorCell, true, child, cause, stats, children); return(true); case Directive.Stop: LogFailure(actorCell, child, cause, directive); ProcessFailure(actorCell, false, child, cause, stats, children); return(true); } return(false); }
/// <summary> /// This is the main entry point: in case of a child’s failure, this method /// must try to handle the failure by resuming, restarting or stopping the /// child (and returning `true`), or it returns `false` to escalate the /// failure, which will lead to this actor re-throwing the exception which /// caused the failure. The exception will not be wrapped. /// This method calls [[Akka.Actor.SupervisorStrategy#LogFailure]], which will /// log the failure unless it is escalated. You can customize the logging by /// setting [[Akka.Actor.SupervisorStrategy#LoggingEnabled]] to `false` and /// do the logging inside the `decider` or override the `LogFailure` method. /// </summary> /// <param name="actorCell">The actor cell.</param> /// <param name="child">The child.</param> /// <param name="cause">The cause.</param> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns> public bool HandleFailure(ActorCell actorCell, ActorRef child, Exception cause) { Directive directive = Handle(child, cause); switch (directive) { case Directive.Escalate: LogFailure(actorCell, child, cause, directive); return(false); case Directive.Resume: LogFailure(actorCell, child, cause, directive); ResumeChild(child, cause); return(true); case Directive.Restart: LogFailure(actorCell, child, cause, directive); ProcessFailure(actorCell, true, child, cause); return(true); case Directive.Stop: LogFailure(actorCell, child, cause, directive); ProcessFailure(actorCell, false, child, cause); return(true); } return(false); }
/// <summary> /// TBD /// </summary> /// <returns>TBD</returns> protected virtual ActorCell NewCell() { var actorCell = new ActorCell(System, this, Props, Dispatcher, Supervisor); actorCell.Init(false, MailboxType); return(actorCell); }
protected AbstractStash(IActorContext context, int capacity = 100) { Context = context; Self = Context.Self; TheStash = new LinkedList <Envelope>(); ActorCell = context.AsInstanceOf <ActorCell>(); Capacity = 100; }
/// <summary> /// Actors the of. /// </summary> /// <param name="system">The system.</param> /// <param name="props">The props.</param> /// <param name="supervisor">The supervisor.</param> /// <param name="path">The path.</param> /// <param name="systemService">Is this a child actor under the system guardian?</param> /// <returns>InternalActorRef.</returns> public override InternalActorRef ActorOf(ActorSystem system, Props props, InternalActorRef supervisor, ActorPath path, bool systemService = false) { ActorCell cell = null; Mailbox mailbox = System.Mailboxes.FromConfig(props.Mailbox); Deploy configDeploy = System.Provider.Deployer.Lookup(path); var deploy = configDeploy ?? props.Deploy ?? Deploy.None; if (deploy.Mailbox != null) { props = props.WithMailbox(deploy.Mailbox); } if (deploy.Dispatcher != null) { props = props.WithDispatcher(deploy.Dispatcher); } if (deploy.Scope is RemoteScope) { } if (string.IsNullOrEmpty(props.Mailbox)) { // throw new NotSupportedException("Mailbox can not be configured as null or empty"); } if (string.IsNullOrEmpty(props.Dispatcher)) { //TODO: fix this.. // throw new NotSupportedException("Dispatcher can not be configured as null or empty"); } if (props.Deploy != null && props.Deploy.Scope is RemoteScope) { throw new NotSupportedException("LocalActorRefProvider can not deploy remote"); } if (props.RouterConfig is NoRouter || props.RouterConfig == null) { props = props.WithDeploy(deploy); cell = new ActorCell(system, supervisor, props, path, mailbox); } else { //if no Router config value was specified, override with procedural input if (deploy.RouterConfig is NoRouter) { deploy = deploy.WithRouterConfig(props.RouterConfig); } //TODO: make this work for remote actor ref provider cell = NewRouterCell(system, supervisor, path, props, mailbox, deploy); } cell.NewActor(); // parentContext.Watch(cell.Self); return(cell.Self); }
/// <summary> /// Inheritors should only call this constructor /// </summary> internal protected LocalActorRef(ActorSystem system, Props props, MessageDispatcher dispatcher, Func<Mailbox> createMailbox, IInternalActorRef supervisor, ActorPath path, Func<LocalActorRef, ActorCell> createActorCell) //TODO: switch from Func<Mailbox> createMailbox to MailboxType mailboxType { _system = system; _props = props; _dispatcher = dispatcher; _createMailbox = createMailbox; _supervisor = supervisor; _path = path; _cell = createActorCell(this); }
//This mimics what's done in Akka`s construction of an LocalActorRef. //The actorCell is created in the overridable newActorCell() during creation of the instance. //Since we don't want calls to virtual members in C# we must supply it. // //This is the code from Akka: // private[akka] class LocalActorRef private[akka] ( // _system: ActorSystemImpl, // _props: Props, // _dispatcher: MessageDispatcher, // _mailboxType: MailboxType, // _supervisor: InternalActorRef, // override val path: ActorPath) extends ActorRefWithCell with LocalRef { // private val actorCell: ActorCell = newActorCell(_system, this, _props, _dispatcher, _supervisor) // actorCell.init(sendSupervise = true, _mailboxType) // ... // } public LocalActorRef(ActorSystemImpl system, Props props, MessageDispatcher dispatcher, Func <Mailbox> createMailbox, InternalActorRef supervisor, ActorPath path) //TODO: switch from Func<Mailbox> createMailbox to MailboxType mailboxType : this(system, props, dispatcher, createMailbox, supervisor, path, self => { var cell = new ActorCell(system, self, props, dispatcher, supervisor); cell.Init(sendSupervise: true, createMailbox: createMailbox); return(cell); }) { //Intentionally left blank }
/// <summary> /// Inheritors should only call this constructor /// </summary> internal protected LocalActorRef(ActorSystem system, Props props, MessageDispatcher dispatcher, Func <Mailbox> createMailbox, InternalActorRef supervisor, ActorPath path, Func <LocalActorRef, ActorCell> createActorCell) //TODO: switch from Func<Mailbox> createMailbox to MailboxType mailboxType { _system = system; _props = props; _dispatcher = dispatcher; _createMailbox = createMailbox; _supervisor = supervisor; _path = path; _cell = createActorCell(this); }
protected override void ProcessFailure(ActorCell actorCell, bool restart, ActorRef child, Exception cause) { if (restart) { RestartChild(child, cause, false); } else { child.AsInstanceOf <InternalActorRef>().Stop(); } }
/// <summary> /// Initializes this instance. /// </summary> public virtual void Init() { RootPath = new RootActorPath(Address); TempNode = RootPath / "temp"; RootCell = new ActorCell(System, "", new ConcurrentQueueMailbox()); DeadLetters = new DeadLetterActorRef(this, RootPath / "deadLetters", System.EventStream); Guardian = (LocalActorRef)RootCell.ActorOf <GuardianActor>("user"); SystemGuardian = (LocalActorRef)RootCell.ActorOf <GuardianActor>("system"); TempContainer = new VirtualPathContainer(this, TempNode, null); }
//This mimics what's done in Akka`s construction of an LocalActorRef. //The actorCell is created in the overridable newActorCell() during creation of the instance. //Since we don't want calls to virtual members in C# we must supply it. // //This is the code from Akka: // private[akka] class LocalActorRef private[akka] ( // _system: ActorSystemImpl, // _props: Props, // _dispatcher: MessageDispatcher, // _mailboxType: MailboxType, // _supervisor: InternalActorRef, // override val path: ActorPath) extends ActorRefWithCell with LocalRef { // private val actorCell: ActorCell = newActorCell(_system, this, _props, _dispatcher, _supervisor) // actorCell.init(sendSupervise = true, _mailboxType) // ... // } public LocalActorRef(ActorSystemImpl system, Props props, MessageDispatcher dispatcher, Func<Mailbox> createMailbox, IInternalActorRef supervisor, ActorPath path) //TODO: switch from Func<Mailbox> createMailbox to MailboxType mailboxType : this(system, props, dispatcher, createMailbox, supervisor, path, self => { var cell= new ActorCell(system, self, props, dispatcher, supervisor); cell.Init(sendSupervise: true, createMailbox: createMailbox); return cell; }) { //Intentionally left blank }
/// <summary> /// Initializes this instance. /// </summary> public virtual void Init() { RootPath = new RootActorPath(Address); TempNode = RootPath / "temp"; RootCell = new ActorCell(System, "", new ConcurrentQueueMailbox()); DeadLetters = new DeadLetterActorRef(this, RootPath / "deadLetters", System.EventStream); Guardian = (LocalActorRef)RootCell.ActorOf<GuardianActor>("user"); SystemGuardian = (LocalActorRef)RootCell.ActorOf<GuardianActor>("system"); TempContainer = new VirtualPathContainer(this, TempNode, null); }
public void UseThreadContext(Action action) { ActorCell tmp = Current; current = this; try { action(); } finally { //ensure we set back the old context current = tmp; } }
protected override void ProcessFailure(ActorCell actorCell, bool restart, ActorRef child, Exception cause) { if (restart) { foreach (var c in actorCell.GetChildren().ToArray()) { RestartChild(child, cause, false); } } else { foreach (var c in actorCell.GetChildren().ToArray()) { child.AsInstanceOf <InternalActorRef>().Stop(); } } }
/// <summary> /// TBD /// </summary> /// <param name="name">TBD</param> /// <returns>TBD</returns> public override IActorRef GetChild(IEnumerable <string> name) { var current = (IActorRef)this; if (!name.Any()) { return(current); } var next = name.FirstOrDefault() ?? ""; switch (next) { case "..": return(Parent.GetChild(name.Skip(1))); case "": return(ActorRefs.Nobody); default: var nameAndUid = ActorCell.SplitNameAndUid(next); if (Lookup.TryGetChildStatsByName(nameAndUid.Name, out var stats)) { var crs = stats as ChildRestartStats; var uid = nameAndUid.Uid; if (crs != null && (uid == ActorCell.UndefinedUid || uid == crs.Uid)) { if (name.Skip(1).Any()) { return(crs.Child.GetChild(name.Skip(1))); } else { return(crs.Child); } } } else if (Lookup is ActorCell cell && cell.TryGetFunctionRef(nameAndUid.Name, nameAndUid.Uid, out var functionRef)) { return(functionRef); } return(ActorRefs.Nobody); } }
/// <summary> /// Logs the failure. /// </summary> /// <param name="actorCell">The actor cell.</param> /// <param name="child">The child.</param> /// <param name="cause">The cause.</param> /// <param name="directive">The directive.</param> protected virtual void LogFailure(ActorCell actorCell, ActorRef child, Exception cause, Directive directive) { switch (directive) { case Directive.Resume: actorCell.System.EventStream.Publish(new Warning(child.Path.ToString(), GetType(), cause.Message)); break; case Directive.Escalate: break; default: //case Directive.Restart: //case Directive.Stop: actorCell.System.EventStream.Publish(new Error(cause, child.Path.ToString(), GetType(), cause.Message)); break; } }
public override void SetActor(ActorCell actorCell) { if (actorCell.Self is ActorRefWithCell) { var actorType = actorCell.Props.Type; if (!typeof (ActorBase).IsAssignableFrom(actorType)) throw new ArgumentException( string.Format("Don't use anonymouse actor classes, actor class for {0} was [{1}]", actorCell, actorType.FullName)); // StreamTcpManager is allowed to use another dispatcher if (actorType.FullName.StartsWith("Akka.Streams.")) throw new ArgumentException( string.Format( "{0} with actor class [{1}] must not run on default dispatcher in tests. Did you forget to define `props.withDispatcher` when creating the actor? Or did you forget to configure the `akka.stream.materializer` setting accordingly or force the dispatcher using `ActorMaterializerSettings(sys).withDispatcher(\"akka.test.stream-dispatcher\")` in the test?", actorCell, actorType.FullName)); } base.SetActor(actorCell); }
/// <summary> /// Resolves the actor reference. /// </summary> /// <param name="actorPath">The actor path.</param> /// <returns>ActorRef.</returns> /// <exception cref="System.NotSupportedException">The provided actor path is not valid in the LocalActorRefProvider</exception> public override ActorRef ResolveActorRef(ActorPath actorPath) { if (Address.Equals(actorPath.Address)) { if (actorPath.Elements.Head() == "temp") { //skip ""/"temp", string[] parts = actorPath.Elements.Drop(1).ToArray(); return(TempContainer.GetChild(parts)); } //standard ActorCell currentContext = RootCell; foreach (string part in actorPath.Elements) { currentContext = ((LocalActorRef)currentContext.Child(part)).Cell; } return(currentContext.Self); } throw new NotSupportedException("The provided actor path is not valid in the LocalActorRefProvider"); }
/// <summary> /// TBD /// </summary> /// <param name="name">TBD</param> /// <returns>TBD</returns> public override IActorRef GetChild(IReadOnlyList <string> name) { if (name.Count == 0) { return(this); } var next = name[0]; switch (next) { case "..": return(Parent.GetChild(name.NoCopySlice(1))); case "": return(ActorRefs.Nobody); default: var(s, uid) = ActorCell.GetNameAndUid(next); if (Lookup.TryGetChildStatsByName(s, out var stats)) { if (stats is ChildRestartStats crs && (uid == ActorCell.UndefinedUid || uid == crs.Uid)) { if (name.Count > 1) { return(crs.Child.GetChild(name.NoCopySlice(1))); } else { return(crs.Child); } } } else if (Lookup is ActorCell cell && cell.TryGetFunctionRef(s, uid, out var functionRef)) { return(functionRef); } return(ActorRefs.Nobody); } }
/// <summary> /// This is the main entry point: in case of a child’s failure, this method /// must try to handle the failure by resuming, restarting or stopping the /// child (and returning `true`), or it returns `false` to escalate the /// failure, which will lead to this actor re-throwing the exception which /// caused the failure. The exception will not be wrapped. /// This method calls [[Akka.Actor.SupervisorStrategy#LogFailure]], which will /// log the failure unless it is escalated. You can customize the logging by /// setting [[Akka.Actor.SupervisorStrategy#LoggingEnabled]] to `false` and /// do the logging inside the `decider` or override the `LogFailure` method. /// </summary> /// <param name="actorCell">The actor cell.</param> /// <param name="child">The child.</param> /// <param name="cause">The cause.</param> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns> public bool HandleFailure(ActorCell actorCell, ActorRef child, Exception cause) { Directive directive = Handle(child, cause); switch (directive) { case Directive.Escalate: LogFailure(actorCell, child, cause, directive); return false; case Directive.Resume: LogFailure(actorCell, child, cause, directive); ResumeChild(child, cause); return true; case Directive.Restart: LogFailure(actorCell, child, cause, directive); ProcessFailure(actorCell, true, child, cause); return true; case Directive.Stop: LogFailure(actorCell, child, cause, directive); ProcessFailure(actorCell, false, child, cause); return true; } return false; }
//This mimics what's done in Akka`s construction of an LocalActorRef. //The actorCell is created in the overridable newActorCell() during creation of the instance. //Since we don't want calls to virtual members in C# we must supply it. // //This is the code from Akka: // private[akka] class LocalActorRef private[akka] ( // _system: ActorSystemImpl, // _props: Props, // _dispatcher: MessageDispatcher, // _mailboxType: MailboxType, // _supervisor: InternalActorRef, // override val path: ActorPath) extends ActorRefWithCell with LocalRef { // private val actorCell: ActorCell = newActorCell(_system, this, _props, _dispatcher, _supervisor) // actorCell.init(sendSupervise = true, _mailboxType) // ... // } public LocalActorRef(ActorSystemImpl system, Props props, MessageDispatcher dispatcher, MailboxType mailboxType, IInternalActorRef supervisor, ActorPath path) { _system = system; _props = props; _dispatcher = dispatcher; MailboxType = mailboxType; _supervisor = supervisor; _path = path; /* * Safe publication of this class’s fields is guaranteed by Mailbox.SetActor() * which is called indirectly from ActorCell.init() (if you’re wondering why * this is at all important, remember that under the CLR readonly fields are only * frozen at the _end_ of the constructor, but we are publishing “this” before * that is reached). * This means that the result of NewActorCell needs to be written to the field * _cell before we call init and start, since we can start using "this" * object from another thread as soon as we run init. */ // ReSharper disable once VirtualMemberCallInContructor _cell = NewActorCell(_system, this, _props, _dispatcher, _supervisor); // _cell needs to be assigned before Init is called. _cell.Init(true, MailboxType); }
/// <summary> /// This is the main entry point: in case of a child’s failure, this method /// must try to handle the failure by resuming, restarting or stopping the /// child (and returning `true`), or it returns `false` to escalate the /// failure, which will lead to this actor re-throwing the exception which /// caused the failure. The exception will not be wrapped. /// This method calls <see cref="Akka.Actor.SupervisorStrategy"/>, which will /// log the failure unless it is escalated. You can customize the logging by /// setting <see cref="Akka.Actor.SupervisorStrategy" /> to `false` and /// do the logging inside the `decider` or override the `LogFailure` method. /// </summary> /// <param name="actorCell">The actor cell.</param> /// <param name="cause">The cause.</param> /// <param name="failedChildStats">The stats for the failed child.</param> /// <param name="allChildren"></param> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns> public bool HandleFailure(ActorCell actorCell, Exception cause, ChildRestartStats failedChildStats, IReadOnlyCollection<ChildRestartStats> allChildren) { var child = failedChildStats.Child; var directive = Handle(child, cause); switch (directive) { case Directive.Escalate: LogFailure(actorCell, child, cause, directive); return false; case Directive.Resume: LogFailure(actorCell, child, cause, directive); ResumeChild(child, cause); return true; case Directive.Restart: LogFailure(actorCell, child, cause, directive); ProcessFailure(actorCell, true, cause, failedChildStats, allChildren); return true; case Directive.Stop: LogFailure(actorCell, child, cause, directive); ProcessFailure(actorCell, false, cause, failedChildStats, allChildren); return true; } return false; }
public override void Detach(ActorCell cell) { //shut down the dedicated thread pool _dedicatedThreadPool.Dispose(); }
/// <summary> /// Dispatches a <see cref="ISystemMessage"/> from a mailbox to an <see cref="ActorCell"/> /// </summary> public virtual void SystemDispatch(ActorCell cell, Envelope envelope) { cell.SystemInvoke(envelope); }
protected virtual ActorCell NewCell() { var actorCell = new ActorCell(_system, this, _props, _dispatcher, _supervisor); actorCell.Init(sendSupervise: false, createMailbox: _createMailbox); return actorCell; }
/// <summary> /// Creates a new <see cref="ChildActorPath"/> with the specified parent <paramref name="path"/> /// and the specified <paramref name="name"/>. /// </summary> /// <param name="path">The parent path of the newly created actor path</param> /// <param name="name">The name of child actor path</param> /// <returns>A newly created <see cref="ChildActorPath"/></returns> public static ActorPath operator /(ActorPath path, string name) { var nameAndUid = ActorCell.SplitNameAndUid(name); return(new ChildActorPath(path, nameAndUid.Name, nameAndUid.Uid)); }
public void Stop() { SendSystemMessage(Terminate.Instance, ActorCell.GetCurrentSelfOrNoSender()); }
public void Resume(Exception causedByFailure) { SendSystemMessage(new Resume(causedByFailure), ActorCell.GetCurrentSelfOrNoSender()); }
/// <summary> /// Forwards the message using the current Sender /// </summary> /// <param name="message"></param> public void Forward(object message) { var sender = ActorCell.GetCurrentSenderOrNoSender(); TellInternal(message, sender); }
/// <summary> /// Attaches the dispatcher to the <see cref="ActorCell"/> /// /// <remarks> /// Practically, doesn't do very much right now - dispatchers aren't responsible for creating /// mailboxes in Akka.NET /// </remarks> /// </summary> /// <param name="cell">The ActorCell belonging to the actor who's attaching to this dispatcher.</param> public virtual void Attach(ActorCell cell) { Register(cell); RegisterForExecution(cell.Mailbox, false, true); }
/// <summary> /// Dispatches a <see cref="SystemMessage"/> from a mailbox to an <see cref="ActorCell"/> /// </summary> public virtual void SystemDispatch(ActorCell cell, SystemMessage message) { var mbox = cell.Mailbox; mbox.SystemEnqueue(cell.Self, message); RegisterForExecution(mbox, false, true); }
/// <summary> /// Dispatches a user-defined message from a mailbox to an <see cref="ActorCell"/> /// </summary> public virtual void Dispatch(ActorCell cell, Envelope envelope) { var mbox = cell.Mailbox; mbox.Enqueue(cell.Self, envelope); RegisterForExecution(mbox, true, false); }
/// <summary> /// Creates and returns a <see cref="Mailbox"/> for the given actor. /// </summary> /// <param name="cell">Cell of the actor.</param> /// <param name="mailboxType">The mailbox configurator.</param> /// <returns>The configured <see cref="Mailbox"/> for this actor.</returns> internal Mailbox CreateMailbox(ActorCell cell, MailboxType mailboxType) { return new Mailbox(mailboxType.Create(cell.Self, cell.System)); }
/// <summary> /// Detaches the dispatcher to the <see cref="ActorCell"/> /// /// <remarks> /// Only really used in dispatchers with 1:1 relationship with dispatcher. /// </remarks> /// </summary> /// <param name="cell">The ActorCell belonging to the actor who's detaching from this dispatcher.</param> public virtual void Detach(ActorCell cell) { }
/// <summary> /// INTERNAL API /// /// If you override it, you must call it. But only ever once. See <see cref="Detach"/> for the only invocation /// </summary> /// <param name="actor">The actor who is unregistering</param> internal virtual void Unregister(ActorCell actor) { if (DebugDispatcher) Actors.Value.Remove(this, (IInternalActorRef)actor.Self); AddInhabitants(-1); var mailbox = actor.SwapMailbox(Mailboxes.DeadLetterMailbox); mailbox.BecomeClosed(); mailbox.CleanUp(); }
public void Suspend() { SendSystemMessage(Akka.Dispatch.SysMsg.Suspend.Instance, ActorCell.GetCurrentSelfOrNoSender()); }
/// <summary> /// After the call to this method, the dispatcher mustn't begin any new message processing for the specified reference /// </summary> /// <param name="actorCell">The cell of the actor whose mailbox will be suspended.</param> internal virtual void Suspend(ActorCell actorCell) { var mbox = actorCell.Mailbox; if (mbox.Actor == actorCell && mbox.Dispatcher == this) //make sure everything is referring to the same instance { mbox.Suspend(); } }
public void Restart(Exception cause) { SendSystemMessage(new Recreate(cause), ActorCell.GetCurrentSelfOrNoSender()); }
/// <summary> /// After the call to this method, the dispatcher must begin any new message processing for the specified reference /// </summary> /// <param name="actorCell">The cell of the actor whose mailbox will be resumed.</param> internal virtual void Resume(ActorCell actorCell) { var mbox = actorCell.Mailbox; if (mbox.Actor == actorCell && mbox.Dispatcher == this && mbox.Resume()) //make sure everything is referring to the same instance { RegisterForExecution(mbox, false, false); // force the mailbox to re-run after resume } }
internal override void Unregister(ActorCell actor) { base.Unregister(actor); _owner = null; }
internal ActorTaskScheduler(ActorCell actorCell) { _actorCell = actorCell; }
public ActorCellKeepingSynchronizationContext(ActorCell cell) { _cell = cell; }
public static void Schedule(this IScheduler scheduler, TimeSpan initialDelay, TimeSpan interval, IActorRef receiver, object message, CancellationToken cancellationToken) { var sender = ActorCell.GetCurrentSelfOrNoSender(); scheduler.Advanced.ScheduleRepeatedly(initialDelay, interval, () => receiver.Tell(message, sender), null); }
public static void ScheduleOnce(this IScheduler scheduler, TimeSpan initialDelay, IActorRef receiver, object message) { var sender = ActorCell.GetCurrentSelfOrNoSender(); scheduler.Advanced.ScheduleOnce(initialDelay, () => receiver.Tell(message, sender), null); }
/// <summary> /// Attaches an ActorCell to the Mailbox. /// </summary> /// <param name="actorCell"></param> public void SetActor(ActorCell actorCell) { _actorCell = actorCell; }
public bool HandleFailure(ActorCell actorCell, Exception cause, ChildRestartStats failedChildStats, IReadOnlyCollection <ChildRestartStats> allChildren) { return(HandleFailure(actorCell, failedChildStats.Child, cause, failedChildStats, allChildren)); }
/// <summary> /// Dispatches a user-defined message from a mailbox to an <see cref="ActorCell"/> /// </summary> public virtual void Dispatch(ActorCell cell, Envelope envelope) { cell.Invoke(envelope); }
/// <summary> /// Processes the failure. /// </summary> /// <param name="actorCell">The actor cell.</param> /// <param name="restart">if set to <c>true</c> [restart].</param> /// <param name="child">The child.</param> /// <param name="cause">The cause.</param> private void ProcessFailure(ActorCell actorCell, bool restart, ActorRef child, Exception cause) { if (restart) { RestartChild(child, cause, false); } else { child.AsInstanceOf<InternalActorRef>().Stop(); } /* if (children.nonEmpty) { if (restart && children.forall(_.requestRestartPermission(retriesWindow))) children foreach (crs ⇒ restartChild(crs.child, cause, suspendFirst = (crs.child != child))) else for (c ← children) context.stop(c.child) } */ //if (children.Any()) //{ // if (restart) // { // } // else // { // foreach (var child in children) // { // child.Stop(); // } // } //} }
/// <summary> /// Actors the of. /// </summary> /// <param name="system">The system.</param> /// <param name="props">The props.</param> /// <param name="supervisor">The supervisor.</param> /// <param name="path">The path.</param> /// <returns>InternalActorRef.</returns> public override InternalActorRef ActorOf(ActorSystem system, Props props, InternalActorRef supervisor, ActorPath path) { ActorCell cell = null; Mailbox mailbox = System.Mailboxes.FromConfig(props.Mailbox); Deploy configDeploy = System.Provider.Deployer.Lookup(path); var deploy = configDeploy ?? props.Deploy ?? Deploy.None; if (deploy.Mailbox != null) props = props.WithMailbox(deploy.Mailbox); if (deploy.Dispatcher != null) props = props.WithDispatcher(deploy.Dispatcher); if (deploy.Scope is RemoteScope) { } if (string.IsNullOrEmpty(props.Mailbox)) { // throw new NotSupportedException("Mailbox can not be configured as null or empty"); } if (string.IsNullOrEmpty(props.Dispatcher)) { //TODO: fix this.. // throw new NotSupportedException("Dispatcher can not be configured as null or empty"); } if (props.Deploy != null && props.Deploy.Scope is RemoteScope) { throw new NotSupportedException("LocalActorRefProvider can not deploy remote"); } if (props.RouterConfig is NoRouter || props.RouterConfig == null) { props = props.WithDeploy(deploy); cell = new ActorCell(system, supervisor, props, path, mailbox); } else { //if no Router config value was specified, override with procedural input if (deploy.RouterConfig is NoRouter) { deploy = deploy.WithRouterConfig(props.RouterConfig); } var routerProps = Props.Create<RouterActor>() .WithDeploy(deploy); var routeeProps = props.WithRouter(RouterConfig.NoRouter); cell = new RoutedActorCell(system, supervisor, routerProps, routeeProps, path, mailbox); } cell.NewActor(); // parentContext.Watch(cell.Self); return cell.Self; }
/// <summary> /// INTERNAL API /// /// If you override it, you must still call the base method. But only ever once. See <see cref="Attach"/> for only invocation. /// </summary> /// <param name="actor">The actor we're registering</param> internal virtual void Register(ActorCell actor) { if (DebugDispatcher) Actors.Value.Put(this, (IInternalActorRef)actor.Self); AddInhabitants(1); }
public bool HandleFailure(ActorCell actorCell, Exception cause, ChildRestartStats failedChildStats, IReadOnlyCollection <ChildRestartStats> allChildren) { // for compatibility, since 1.1.2 return(HandleFailure(actorCell, failedChildStats.Child, cause, failedChildStats, allChildren)); }
/// <summary> /// Forwards the message using the current Sender /// </summary> /// <param name="receiver">The actor that receives the forward</param> /// <param name="message">The message to forward</param> public static void Forward(this IActorRef receiver, object message) { var sender = ActorCell.GetCurrentSenderOrNoSender(); receiver.Tell(message, sender); }
/// <summary> /// Detaches the dispatcher to the <see cref="ActorCell"/> /// /// <remarks> /// Only really used in dispatchers with 1:1 relationship with dispatcher. /// </remarks> /// </summary> /// <param name="cell">The ActorCell belonging to the actor who's detaching from this dispatcher.</param> public virtual void Detach(ActorCell cell) { try { Unregister(cell); } finally { IfSensibleToDoSoThenScheduleShutdown(); } }