//
// Copyright (c) 2009, Brian Frank and Andy Frank
// Licensed under the Academic Free License version 3.0
//
// History:
// 26 Mar 09 Brian Frank Creation
//
**
** Controller for a group of actors which manages their
** execution using pooled thread resources.
**
** See [docLang::Actors]`docLang::Actors`
**
@Js
native const class ActorPool
{
**
** It-block constructor
**
new make(|This|? f := null)
**
** Return true if this pool has been stopped or killed. Once a
** a pool is stopped, new messages may not be delivered to any of its
** actors. A stopped pool is not necessarily done until all its
** actors have finished processing. Also see `isDone` and `join`.
**
Bool isStopped()
**
** Return true if this pool has been stopped or killed and all
** its actors have completed processing. If this pool was stopped
** then true indicates that all pending messages in the queues before
** the stop have been fully processed. If this pool was killed,
** then this method returns true once all actors have exited their
** thread. See `join` to block until done.
**
Bool isDone()
**
** Perform an orderly shutdown. Once stopped, no new messages may
** be sent to this pool's actors. However, any pending messages
** will be processed. Note that scheduled messages are *not*
** guaranteed to be processed, only those delivered with 'Actor.send'.
**
** Use `join` to wait for all actors to complete their message queue.
** To perform an immediate shutdown use `kill`. If the pool has
** already been stopped, then do nothing. Return this.
**
This stop()
**
** Perform an unorderly shutdown. Any pending messages which have
** not started processing are cancelled. Actors which are currently
** processing a message will be interrupted. See `stop` to perform
** an orderly shutdown. If the pool has already been killed,
** then do nothing.
**
This kill()
**
** Wait for this pool's actors to fully terminate or until the
** given timeout occurs. A null timeout blocks forever. If this
** method times out, then TimeoutErr is thrown. Throw Err if the
** pool is not stopped. Return this.
**
This join(Duration? timeout := null)
**
** Given a list of one or more actors, return the next actor to use
** to perform load balanced work. The default implemention returns
** the actor with the lowest number of messages in its queue.
**
** NOTE: this is an experimental feature which is subject to change
**
@NoDoc virtual Actor balance(Actor[] actors)
**
** Name to use for the pool and associated threads.
**
const Str name := "ActorPool"
**
** Max number of threads which are used by this pool
** for concurrent actor execution. This value must be
** at least one or greater.
**
const Int maxThreads := 100
**
** Max number of messages that may be queued by actors in this pool.
** Once this limit is reached, any messages sent are immediately rejected
** and their future will raise `QueueOverflowErr`. This limit only applies
** to messages sent via 'send' and 'sendWhenDone'. No limit checking
** is applied to 'sendLater'.
**
const Int maxQueue := 100_000_000
**
** Max duration an actor will work processing messages before yielding its
** thread. Because actors require cooperative multi-tasking we don't
** want to let an actor hog a thread forever and potentially starve out
** other actors waiting for a thread. Note its possible for an actor to
** work longer than this time (especially if its blocking on I/O). However
** once this time has expired, the actor will not process subsequent messages
** in its queue. As an optimization an actor will never yield unless
** the pool has other actors waiting for a thread.
**
** NOTE: this method is marked as NoDoc, it is provided for low level
** access to tune the actor pool, but it is subject to change.
**
@NoDoc const Duration maxTimeBeforeYield := 5sec
}