c# - Akka.net dynamically add child -
there configured actorsystem
actors organized hierarchically following:
/user /processes /process1 /process2 /process3
to generate scheme use next c# code:
// in entry point iactorref processescoordinatoractorref = actorsystem.actorof(props.create<processescoordinatoractor>(), "processes"); // in processescoordinatoractor.cs: iactorref processoneactorref = context.actorof(props.create<proccessactor>(), "process1"); iactorref processtwoactorref = context.actorof(props.create<proccessactor>(), "process2"); iactorref processthreeactorref = context.actorof(props.create<proccessactor>(), "process3");
my problem want add child actor process1
, process2
or process3
entry point code (outside of processactor). hands tied, because iactorref
hides actor instance me.
how solve it?
the child actor has created in context
of parent actor. if want trigger happening outside, send parent message , have create child actor (e.g. createchildactor
). there no way create actor in 1 place, , have "adopted" child of actor.
generally (and without knowing you're trying do), hunch creating actors way down hierarchy top-level / entry-point code not direction go down. should let parent actors within hierarchy job of creating , supervising children.
if had trigger process entry point, send createchildactor
anywhere in hierarchy using actorselection
and/or resolve iactorref
.
here's code sample showing how this, , have subprocess notify coordinator once it's ready (also here fiddle):
using system; using system.threading; using akka.actor; namespace processactors { class program { /// <summary> /// top-level process coordinator actor. /// </summary> public class processescoordinatoractor : receiveactor { public processescoordinatoractor() { receive<createchildactor>(createrequest => { console.writeline("{0} creating child actor: {1}", self.path, createrequest.childname); var child = context.actorof(createrequest.childprops, createrequest.childname); if (createrequest.actortonotify != null) createrequest.actortonotify.tell(new readyforwork(child)); }); receive<readyforwork>(ready => { console.writeline("coordinator sees worker ready: {0}", ready.worker.path); }); receiveany(o => { console.writeline("{0} received {1}", self.path, o); }); } } /// <summary> /// actor given process. /// </summary> public class processactor : receiveactor { public processactor() { receive<createchildactor>(createrequest => { console.writeline("{0} creating child actor: {1}", self.path, createrequest.childname); var child = context.actorof(createrequest.childprops, createrequest.childname); if (createrequest.actortonotify != null) createrequest.actortonotify.tell(new readyforwork(child)); }); receiveany(o => { console.writeline("{0} received {1}", self.path, o); }); } } /// <summary> /// sub-process. /// </summary> public class subprocessactor : receiveactor { public subprocessactor() { receiveany(o => { console.writeline("{0} received {1}", self.path, o); }); } } public static void main(string[] args) { using (var system = actorsystem.create("myactorsystem")) { console.writeline("starting up."); var coordinator = system.actorof(props.create(() => new processescoordinatoractor()), "processes"); var processprops = props.create(() => new processactor()); // create process actors coordinator.tell(new createnewprocess("process1", processprops)); coordinator.tell(new createnewprocess("process2", processprops)); coordinator.tell(new createnewprocess("process3", processprops)); var subprocessprops = props.create(() => new subprocessactor()); // tiny sleep let boot thread.sleep(timespan.frommilliseconds(50)); // handle actor somewhere down in hierarchy var process1 = system.actorselection("/user/processes/process1").resolveone(timespan.fromseconds(1)).result; // create subprocess of process1 , notify coordinator of new subprocess actor process1.tell(new createnewsubprocess("subprocess1", subprocessprops, coordinator)); console.readline(); } } #region messages /// <summary> /// command create childprops actor , notify actor it. /// </summary> public class createchildactor { public createchildactor(string childname, props childprops, iactorref actortonotify) { childname = childname; actortonotify = actortonotify; childprops = childprops; } public createchildactor(string childname, props childprops) : this(childname, childprops, null) { } public props childprops { get; private set; } public string childname { get; private set; } public iactorref actortonotify { get; private set; } } public class createnewprocess : createchildactor { public createnewprocess(string childname, props childprops, iactorref actortonotify) : base(childname, childprops, actortonotify) { } public createnewprocess(string childname, props childprops) : this(childname, childprops, null) { } } public class createnewsubprocess : createchildactor { public createnewsubprocess(string childname, props childprops, iactorref actortonotify) : base(childname, childprops, actortonotify) { } public createnewsubprocess(string childname, props childprops) : this(childname, childprops, null) { } } /// <summary> /// report actor when ready. /// </summary> public class readyforwork { public readyforwork(iactorref worker) { worker = worker; } public iactorref worker { get; private set; } } #endregion } }
Comments
Post a Comment