Beispiel #1
0
        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));
        }
Beispiel #2
0
        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);
            }
        }