internal FunctionRef AddFunctionRef(Action <IActorRef, object> tell, string suffix = "") { var r = GetRandomActorName("$$"); var n = string.IsNullOrEmpty(suffix) ? r : r + "-" + suffix; var childPath = new ChildActorPath(Self.Path, n, NewUid()); var functionRef = new FunctionRef(childPath, SystemImpl.Provider, SystemImpl.EventStream, tell); return(ImmutableInterlocked.GetOrAdd(ref _functionRefsDoNotCallMeDirectly, childPath.Name, functionRef)); }
private InternalActorRef MakeChild(Props props, string name, bool async, bool systemService) { //TODO: Implement SerializeAllCreators // if (cell.system.settings.SerializeAllCreators && !systemService && props.deploy.scope != LocalScope) // try { // val ser = SerializationExtension(cell.system) // props.args forall (arg ⇒ // arg == null || // arg.isInstanceOf[NoSerializationVerificationNeeded] || // ser.deserialize(ser.serialize(arg.asInstanceOf[AnyRef]).get, arg.getClass).get != null) // } catch { // case NonFatal(e) ⇒ throw new IllegalArgumentException(s"pre-creation serialization check failed at [${cell.self.path}/$name]", e) // } // In case we are currently terminating, fail external attachChild requests // (internal calls cannot happen anyway because we are suspended) if (IsTerminating) { throw new InvalidOperationException("Cannot create child while terminating or terminated"); } //reserve the name before we create the actor ReserveChild(name); InternalActorRef actor; try { var childPath = new ChildActorPath(Self.Path, name, NewUid()); actor = _systemImpl.Provider.ActorOf(_systemImpl, props, _self, childPath, systemService: systemService, deploy: null, lookupDeploy: true, async: async); } catch { //if actor creation failed, unreserve the name UnreserveChild(name); throw; } //TODO: When Mailbox has SuspendCount implement this // // mailbox==null during RoutedActorCell constructor, where suspends are queued otherwise // if (mailbox ne null) for (_ ← 1 to mailbox.suspendCount) actor.suspend() //replace the reservation with the real actor InitChild(actor); actor.Start(); return(actor); }
private IInternalActorRef MakeChild(Props props, string name, bool async, bool systemService) { if (_systemImpl.Settings.SerializeAllCreators && !systemService && !(props.Deploy.Scope is LocalScope)) { var ser = _systemImpl.Serialization; if (props.Arguments != null) { foreach (var argument in props.Arguments) { if (argument != null && !(argument is INoSerializationVerificationNeeded)) { var serializer = ser.FindSerializerFor(argument); var bytes = serializer.ToBinary(argument); var manifestSerializer = serializer as SerializerWithStringManifest; if (manifestSerializer != null) { var manifest = manifestSerializer.Manifest(argument); if (ser.Deserialize(bytes, manifestSerializer.Identifier, manifest) == null) { throw new ArgumentException($"Pre-creation serialization check failed at [${_self.Path}/{name}]", nameof(name)); } } else { if (ser.Deserialize(bytes, serializer.Identifier, argument.GetType().TypeQualifiedName()) == null) { throw new ArgumentException($"Pre-creation serialization check failed at [${_self.Path}/{name}]", nameof(name)); } } } } } } // In case we are currently terminating, fail external attachChild requests // (internal calls cannot happen anyway because we are suspended) if (ChildrenContainer.IsTerminating) { throw new InvalidOperationException("Cannot create child while terminating or terminated"); } else { // this name will either be unreserved or overwritten with a real child below ReserveChild(name); IInternalActorRef actor; try { var childPath = new ChildActorPath(Self.Path, name, NewUid()); actor = _systemImpl.Provider.ActorOf(_systemImpl, props, _self, childPath, systemService: systemService, deploy: null, lookupDeploy: true, async: async); } catch { //if actor creation failed, unreserve the name UnreserveChild(name); throw; } if (Mailbox != null && IsFailed) { for (var i = 1; i <= Mailbox.SuspendCount(); i++) { actor.Suspend(); } } //replace the reservation with the real actor InitChild(actor); actor.Start(); return(actor); } }