Class Mailbox.
Наследование: IDisposable
Пример #1
0
        public RoutedActorCell(ActorSystem system, InternalActorRef supervisor, Props routerProps, Props routeeProps, ActorPath path,
            Mailbox mailbox)
            : base(system, supervisor, routerProps, path, mailbox)
        {
            RouteeProps = routeeProps;
            routerConfig = routerProps.RouterConfig;
            Router = routerConfig.CreateRouter(system);
            routerConfig.Match()
                .With<Pool>(r =>
                {
                    var routees = new List<Routee>();
                    for (int i = 0; i < r.NrOfInstances; i++)
                    {
                        var routee = this.ActorOf(RouteeProps);
                        routees.Add(new ActorRefRoutee(routee));
                    }
                    AddRoutees(routees.ToArray());
                })
                .With<Group>(r =>
                {
                    var routees = routerConfig.GetRoutees(this).ToArray();
                    AddRoutees(routees);
                });



            Self = new RoutedActorRef(path, this);
        }
Пример #2
0
        public ResizablePoolCell(ActorSystem system, InternalActorRef supervisor, Props routerProps,
            Props routeeProps, ActorPath path, Mailbox mailbox, Pool pool)
            : base(system, supervisor, routerProps, routeeProps, path, mailbox)
        {
            if (pool.Resizer == null)
                throw new ArgumentException("RouterConfig must be a Pool with defined resizer");

            resizer = pool.Resizer;
            this._pool = pool;
            this._resizeCounter = 0;
            this._resizeInProgress = ResizeInProgressState.False;
        }
Пример #3
0
        public void Setup(BenchmarkContext context)
        {
            MsgReceived = context.GetCounter("MsgReceived");
            System = ActorSystem.Create("PerfSys");
            Action<IActorDsl> actor = d => d.ReceiveAny((o, c) =>
            {
                MsgReceived.Increment();
            });
            TestActor = System.ActorOf(Props.Create(() => new Act(actor)), "testactor");
            var id = TestActor.Ask<ActorIdentity>(new Identify(null), TimeSpan.FromSeconds(3)).Result;

            Mailbox = new Mailbox(new UnboundedMessageQueue());
            Mailbox.SetActor(TestActor.AsInstanceOf<RepointableActorRef>().Underlying.AsInstanceOf<ActorCell>());
        }
Пример #4
0
        public void Init(bool sendSupervise, Func<Mailbox> createMailbox /*, MailboxType mailboxType*/) //TODO: switch from  Func<Mailbox> createMailbox to MailboxType mailboxType
        {
            var mailbox = createMailbox(); //Akka: dispatcher.createMailbox(this, mailboxType)
            Dispatcher.Attach(this);
            mailbox.Setup(Dispatcher);
            mailbox.SetActor(this);
            _mailbox = mailbox;

            var createMessage = new Create();
            // AKKA:
            //   /*
            //    * The mailboxType was calculated taking into account what the MailboxType
            //    * has promised to produce. If that was more than the default, then we need
            //    * to reverify here because the dispatcher may well have screwed it up.
            //    */
            //// we need to delay the failure to the point of actor creation so we can handle
            //// it properly in the normal way
            //val actorClass = props.actorClass
            //val createMessage = mailboxType match {
            //    case _: ProducesMessageQueue[_] if system.mailboxes.hasRequiredType(actorClass) ⇒
            //    val req = system.mailboxes.getRequiredType(actorClass)
            //    if (req isInstance mbox.messageQueue) Create(None)
            //    else {
            //        val gotType = if (mbox.messageQueue == null) "null" else mbox.messageQueue.getClass.getName
            //        Create(Some(ActorInitializationException(self,
            //        s"Actor [$self] requires mailbox type [$req] got [$gotType]")))
            //    }
            //    case _ ⇒ Create(None)
            //}

            //swapMailbox(mbox)
            //mailbox.setActor(this)

            //// ➡➡➡ NEVER SEND THE SAME SYSTEM MESSAGE OBJECT TO TWO ACTORS ⬅⬅⬅
            //mailbox.systemEnqueue(self, createMessage)
            var self = Self;
            mailbox.Post(self, new Envelope {Message = createMessage, Sender = self});

            if(sendSupervise)
            {
                Parent.Tell(new Supervise(self, async: false), self);
            }
        }
Пример #5
0
        /// <summary>
        /// Posts the specified envelope.
        /// </summary>
        /// <param name="receiver"></param>
        /// <param name="envelope"> The envelope. </param>
        public override void Post(IActorRef receiver, Envelope envelope)
        {
            if (_isClosed)
            {
                return;
            }

            hasUnscheduledMessages = true;
            if (envelope.Message is ISystemMessage)
            {
                Mailbox.DebugPrint("{0} enqueued system message {1} to {2}", ActorCell.Self, envelope, ActorCell.Self.Equals(receiver) ? "itself" : receiver.ToString());
                _systemMessages.Enqueue(envelope);
            }
            else
            {
                Mailbox.DebugPrint("{0} enqueued message {1} to {2}", ActorCell.Self, envelope, ActorCell.Self.Equals(receiver) ? "itself" : receiver.ToString());
                _userMessages.Enqueue(envelope);
            }

            Schedule();
        }
Пример #6
0
        /// <summary>
        ///     Posts the specified envelope.
        /// </summary>
        /// <param name="envelope">The envelope.</param>
        public override void Post(Envelope envelope)
        {
            if (_isClosed)
            {
                return;
            }

            hasUnscheduledMessages = true;
            if (envelope.Message is SystemMessage)
            {
                Mailbox.DebugPrint(ActorCell.Self + " enqueued system message " + envelope);
                _systemMessages.Enqueue(envelope);
            }
            else
            {
                Mailbox.DebugPrint(ActorCell.Self + " enqueued message " + envelope);
                _userMessages.Enqueue(envelope);
            }

            Schedule();
        }
Пример #7
0
        private void Run()
        {
            if (_isClosed)
            {
                return;
            }

            var throughputDeadlineTime = dispatcher.ThroughputDeadlineTime;

            ActorCell.UseThreadContext(() =>
            {
                //if ThroughputDeadlineTime is enabled, start a stopwatch
                if (throughputDeadlineTime.HasValue && throughputDeadlineTime.Value > 0)
                {
                    if (_deadLineTimer != null)
                    {
                        _deadLineTimer.Restart();
                    }
                    else
                    {
                        _deadLineTimer = Stopwatch.StartNew();
                    }
                }

                //we are about to process all enqueued messages
                hasUnscheduledMessages = false;
                Envelope envelope;

                //start with system messages, they have the highest priority
                while (_systemMessages.TryDequeue(out envelope))
                {
                    Mailbox.DebugPrint(ActorCell.Self + " processing system message " + envelope);
                    // TODO: Add + " with " + ActorCell.GetChildren());
                    dispatcher.SystemDispatch(ActorCell, envelope);
                }

                //we should process x messages in this run
                var left = dispatcher.Throughput;

                //try dequeue a user message
                while (!IsSuspended && !_isClosed && _userMessages.TryDequeue(out envelope))
                {
                    Mailbox.DebugPrint(ActorCell.Self + " processing message " + envelope);

                    //run the receive handler
                    dispatcher.Dispatch(ActorCell, envelope);

                    //check if any system message have arrived while processing user messages
                    if (_systemMessages.TryDequeue(out envelope))
                    {
                        //handle system message
                        Mailbox.DebugPrint(ActorCell.Self + " processing system message " + envelope);
                        // TODO: Add + " with " + ActorCell.GetChildren());
                        dispatcher.SystemDispatch(ActorCell, envelope);
                        break;
                    }
                    left--;
                    if (_isClosed)
                    {
                        return;
                    }

                    //if deadline time have expired, stop and break
                    if (throughputDeadlineTime.HasValue && throughputDeadlineTime.Value > 0 &&
                        _deadLineTimer.Elapsed.Ticks > throughputDeadlineTime.Value)
                    {
                        _deadLineTimer.Stop();
                        break;
                    }

                    //we are done processing messages for this run
                    if (left == 0)
                    {
                        break;
                    }
                }

                Interlocked.Exchange(ref status, MailboxStatus.Idle);

                //there are still messages that needs to be processed
                if (_systemMessages.Count > 0 || (!IsSuspended && _userMessages.Count > 0))
                {
                    //we still need has unscheduled messages for external info.
                    //e.g. repointable actor ref uses it
                    //TODO: will this be enough for external parties to work?
                    hasUnscheduledMessages = true;

                    //this is subject of a race condition
                    //but that doesn't matter, since if the above "if" misses
                    //the "Post" that adds the new message will still schedule
                    //this specific call is just to deal with existing messages
                    //that wasn't scheduled due to dispatcher throughput being reached
                    //or system messages arriving during user message processing
                    Schedule();
                }
            });
        }
Пример #8
0
 /// <summary>
 /// INTERNAL API
 /// 
 /// Suggest to register the provided mailbox for execution
 /// </summary>
 /// <param name="mbox">The mailbox</param>
 /// <param name="hasMessageHint">Do we have any messages?</param>
 /// <param name="hasSystemMessageHint">Do we have any system messages?</param>
 /// <returns><c>true</c> if the <see cref="Mailbox"/> was scheduled for execution, otherwise <c>false</c>.</returns>
 internal bool RegisterForExecution(Mailbox mbox, bool hasMessageHint, bool hasSystemMessageHint)
 {
     if (mbox.CanBeScheduledForExecution(hasMessageHint, hasSystemMessageHint)) //This needs to be here to ensure thread safety and no races
     {
         if (mbox.SetAsScheduled())
         {
             ExecuteTask(mbox);
             return true;
         }
         return false;
     }
     return false;
 }
        internal Mailbox SwapMailbox(Mailbox mailbox)
        {
            Mailbox.DebugPrint("{0} Swapping mailbox to {1}", Self, mailbox);
            var ret = _mailboxDoNotCallMeDirectly;
#pragma warning disable 420
            Interlocked.Exchange(ref _mailboxDoNotCallMeDirectly, mailbox);
#pragma warning restore 420
            return ret;
        }
Пример #10
0
        private static InternalActorRef LocalActorOf(ActorSystem system, Props props, InternalActorRef supervisor,
            ActorPath path, Mailbox mailbox)
        {
            ActorCell cell = null;
            if (props.RouterConfig is NoRouter || props.RouterConfig == null) //TODO: should not need nullcheck here
            {
                cell = new ActorCell(system, supervisor, props, path, mailbox);
            }
            else
            {
                var routeeProps = props.WithRouter(RouterConfig.NoRouter);
                cell = new RoutedActorCell(system, supervisor, props, routeeProps, path, mailbox);
            }

            cell.NewActor();
            //   parentContext.Watch(cell.Self);
            return cell.Self;
        }
Пример #11
0
        private InternalActorRef RemoteActorOf(ActorSystem system, Props props, InternalActorRef supervisor,
            ActorPath path, Mailbox mailbox)
        {
            var scope = (RemoteScope) props.Deploy.Scope;
            Deploy d = props.Deploy;
            Address addr = scope.Address;

            if (HasAddress(addr))
            {
                return LocalActorOf(System, props, supervisor, path, mailbox);
            }

            Address localAddress = Transport.LocalAddressForRemote(addr);

            ActorPath rpath = (new RootActorPath(addr)/"remote"/localAddress.Protocol/localAddress.HostPort()/
                               path.Elements.Drop(1).ToArray()).
                WithUid(path.Uid);
            var remoteRef = new RemoteActorRef(Transport, localAddress, rpath, supervisor, props, d);
            remoteRef.Start();
            return remoteRef;
        }
Пример #12
0
        private void Run()
        {
            if (_isClosed)
            {
                return;
            }

            ActorCell.UseThreadContext(() =>
            {
                //if ThroughputDeadlineTime is enabled, start a stopwatch
                if (dispatcher.ThroughputDeadlineTime.HasValue && dispatcher.ThroughputDeadlineTime.Value > 0)
                {
                    if (_deadLineTimer != null)
                    {
                        _deadLineTimer.Restart();
                    }
                    else
                    {
                        _deadLineTimer = Stopwatch.StartNew();
                    }
                }

                //we are about to process all enqueued messages
                hasUnscheduledMessages = false;
                Envelope envelope;

                //start with system messages, they have the highest priority
                while (_systemMessages.TryDequeue(out envelope))
                {
                    Mailbox.DebugPrint(ActorCell.Self + " processing system message " + envelope); // TODO: Add + " with " + ActorCell.GetChildren());
                    ActorCell.SystemInvoke(envelope);
                }

                //we should process x messages in this run
                int left = dispatcher.Throughput;

                //try dequeue a user message
                while (!_isSuspended && !_isClosed && _userMessages.TryDequeue(out envelope))
                {
                    Mailbox.DebugPrint(ActorCell.Self + " processing message " + envelope);

                    //run the receive handler
                    ActorCell.Invoke(envelope);

                    //check if any system message have arrived while processing user messages
                    if (_systemMessages.TryDequeue(out envelope))
                    {
                        //handle system message
                        Mailbox.DebugPrint(ActorCell.Self + " processing system message " + envelope); // TODO: Add + " with " + ActorCell.GetChildren());
                        ActorCell.SystemInvoke(envelope);
                        break;
                    }
                    left--;
                    if (_isClosed)
                    {
                        return;
                    }

                    //if deadline time have expired, stop and break
                    if (dispatcher.ThroughputDeadlineTime.HasValue && dispatcher.ThroughputDeadlineTime.Value > 0 &&
                        _deadLineTimer.ElapsedTicks > dispatcher.ThroughputDeadlineTime.Value)
                    {
                        _deadLineTimer.Stop();
                        break;
                    }

                    //we are done processing messages for this run
                    if (left == 0)
                    {
                        break;
                    }
                }

                //there are still messages that needs to be processed
                if (_systemMessages.Count > 0 || (!_isSuspended && _userMessages.Count > 0))
                {
                    hasUnscheduledMessages = true;
                }

                if (hasUnscheduledMessages)
                {
                    dispatcher.Schedule(Run);
                }
                else
                {
                    Interlocked.Exchange(ref status, MailboxStatus.Idle);
                }
            });
        }
Пример #13
0
        //TODO: real akka does this in the RoutedActorRef
        //Keep this here for now?
        public static ActorCell NewRouterCell(ActorSystem system, InternalActorRef supervisor, ActorPath path, Props props, Mailbox mailbox,Deploy deploy)
        {
            var routerProps = Props.Empty.WithDeploy(deploy);
            var routeeProps = props.WithRouter(RouterConfig.NoRouter);

            if (routerProps.RouterConfig is Pool)
            {
                var p = routerProps.RouterConfig.AsInstanceOf<Pool>();
                if (p.Resizer != null)
                {
                    //if there is a resizer, use ResizablePoolCell
                    return new ResizablePoolCell(system, supervisor, routerProps, routeeProps, path, mailbox, p);
                }               
            }
            //Use RoutedActorCell for all other routers
            return new RoutedActorCell(system, supervisor, routerProps, routeeProps, path, mailbox);
        }