## Reference

Actors.ActorType

The star of the show (but not really)

This holds internal state for an Actor, it wraps the user defined state value. We usually think of the Actor as being the state value rather than this structure which is mostely hidden. It is rare that a user will need to access this directly. Usually Actors are referenced by an Id and we get the actor's details by calling accessor functions on either the Id or the Scene.

If you do access this, then you need to be careful to avoid concurrency violations.

Type Parameters

• S The type of the user defined actor state.
• M The message types the actor accepts, usually Any.

It is rare to set M, but if it is set then it should include at least Leave!.

Actors.IdType

The Address of an Actor

This is a safe reference to an Actor. It is most commonly used to send messages to an Actor. However many accessor methods take an Addr to safely get or set some Actor's internals or associated data.

Warning

This will grow in size as remote actors are added.

Type Parameters

• S The type of the actor state.
• M The message types the actor accepts, usually Any.
Actors.SceneType

The context of message processing

Contains common information which is used by many different methods during message handling. You should assume that the members of this struct are likely to change.

Type Parameters

• S The type of the current Actor's state. This is commonly specified when adding a method for hear (amongst much else).

• M The message types accepted by the current Actor, usually Any.

Actors.StageType

The Root Actor

This contains the addresses for all the actors and bootstraps the play. Currently all actors are created by sending messages to the Stage although this will probably change in the future.

Any messages which the Stage can not handle, it forwards to the play.

The Stage bootstraps itself by putting the PreGenesis! message in its inbox. It processes this message first then sends Genesis! to the actor specified by play!.

It is unusual for the user to access this directly or override its behaviour. Most things can be achieved by creating a new AbsMinder type or allowing messages to be forwarded to the Play actor.

Members

• actors::Actors.AddressBook

All the Actors in the play

• time_to_leave::Union{Nothing, Timer}

Grace period timer before force leaving

• play::Id

User defined play Actor

Actors.TreeMinderType

Organises actors into a hieracy or tree structure. This is used as the default AbsMinder for the play.

When an actor with this minder uses invite! the returned actor will be a child of the current actor (the current actor being the parent). An actor may have many children, but only a single parent.

• If a child actor dies then the parent recieves Died!. By default actors don't know how to handle this so they will also die. (In any case the death will be logged).

• If a parent leaves or dies, then its children are also asked to Leave!.

If you don't wish for an actor to die when one of its children do, then define hear for the Died! message.

Members

• root::Id

• minded::Union{Nothing, Id}

• children::Set{Id}

Actors.TroupeType

A group of Actor's

Messages shouted at the Troupe will be broadcast to the all the Actor's in it. To send a message to the Troupe itself, just use say.

Example

Where a1..a3 are Actor Id's

g = enter!(s, Troupe(a1, a2, a3))
shout(s, g, Leave!())
say(s, g, Leave!())

Members

• as::Array{Id,1}

The addresses of the Actors in a Troupe

Actors.asyncMethod

Similar to @async, but notifies the calling Actor if it fails.

This allows you to create an asynchronous Task without waiting on it to check for errors. If an exception is thrown, the Actor will send AsyncFail! to itself. By default this will cause TaskFailedException to be thrown thus killing the Actor.

Actors.capture_environmentMethod

This is a workaround for integrating third party libraries which use Task local storage or similar. By default it does nothing and it is probably best to avoid using it. See enter! and play!.

Note that this is not necessary for getting OS "environment variables", which are typically shared amongst threads.

Actors.delegateMethod

Perform some action in a temporary Actor

This creates a new Actor, called a Stooge and uses it to perform some action in parallel.

Warning

Do not use variables captured from the surrounding scope, pass them as args.... The args may be copied to avoid concurrency violations.

Actors.expectMethod

Wait for a message of type R and return it

This will block waiting for a message of the right type. It will cause the Actor to become 'insensitive', meaning that all other messages will be buffered while waiting.

When a message of the right type is recieved, then the buffered messages will be put back in the inbox and the matching message is returned.

In theory this could accept the wrong message if the type matches, but it was from an old request or it was sent for some other reason. One way to avoid this is to delegate the ask request, or the entire operation, to a Stooge which will have a new address.

Actors.hearMethod

Usually called by listen! to handle a message taken from the inbox. The user defines new hear methods to handle messages for different Actor-message type combinations.

It is passed a Scene object which has the Actor state type as the first type parameter. By convention this argument is always called s, if you use a different name it may break some non-essential macros. The other parameter is the message, which is usually called msg, unless you have a more appropriate name, and can be of any type (in a local system).

If hear returns a value it will most likely be ignored (unless you override listen!). If you need to respond to a message then use say or ask.

Actors.inboxMethod

Get the inbox of an Actor

Useful when overriding functions such as listen! or leave!. Otherwise it is quite unusual for the user to call this. You should use say and ask to send messages.

The inbox is how an Actor recieves messages. In a local system the sender directly places a message into the inbox. Currently inboxes are implemented with a Julia Channel which can be safely accessed by multiple threads, however it is generally expected that you don't pop! messages from another actor's inbox unless that actor is dead.

Actors.interact!Method

Like play!, but allows you to send and receive messages from the REPL

Calling this will asynchronously start a play and return a 2-tuple of Scene and Task. The Scene can be used to call various methods in the actor system and the task can be checked to see if the actor system has failed.

The function local_addresses can be used to find out what Id a given actor has.

Warning

This is only intended for interactive use in the Julia REPL or similar scenario.

Example

julia> using Actors

julia> struct Ponger end

julia> struct Echo
who::Id
msg::String
end

julia> Actors.hear(s::Scene{Ponger}, msg::Echo) = say(s, msg.who, msg.msg)

julia> (s, t) = interact!()

julia> me(s)
Actors.Person@1

julia> ponger = enter!(s, Ponger())
Ponger@5

julia> ask(s, ponger, Echo(me(s), "Echo, echo, ..."), String)
"Echo, echo, ..."

5-element Array{Pair{Int64,DataType},1}:
1 => Actors.Person
2 => Actors.Logger{Base.TTY}
4 => Actors.InteractivePlay
5 => Ponger

Actors.listen!Method

Take messages from the inbox and process them

By default this simply takes messages from the inbox and calls hear on them. However you may wish to process some messages specially or do some work inbetween messages, in which case you can override this for a given Actor type.

As a general rule, you should make sure to call hear on a message if you can't process it some other way. Otherwise you will prevent some standard messages from working (such as Leave!).

Actors.play!Method

Start the 'Actor System' or a single Actor

Typically the user calls this method on some value which is used as the 'play' Actor state. This then blocks the calling thread until the Stage is sent Leave! or dies due to an error which was allowed to propagate.

This is also called by enter!, in a new Thread/Task, to run a single Actor. Nothing should happen before or after play! so it contains the Actor's full lifetime (excluding Julia internals).

The liftime of the Actor looks something like:

1. prologue!
2. listen! (unless prologue! errors)
3. epilogue! (unless listen! errors)

Then, if there is an error

1. dieing_breath!

You can override any of the above, so if you are forced to override play!(s::Scene, env) this is considered a library design error. Usually if you feel the need to override any of these, then you should solve the problem with AbsMinder or more message passing instead.

Actors.sayMethod

Send a message asynchronously

This returns immediately and doesn't guarantee the message is processed by the actor specified by to. Nor does it guarantee messages will be delivered in the order say is called.

This may throw an error if, for example, to only accepts certain message types.

This doesn't expect a response from to. For that see ask.

Actors.try_sayMethod

Like say, but less likely to throw an exception if to is dead. This is commonly useful when an unexpected error has occurred and you want to perform some cleanup without knowing which actors are still alive. Under normal operation you should expect other actors to be alive if you are sending them a message.

Note

If, for example, to exceeds the highest known ID in the local Stage then this will still throw a BoundsError. This is to help prevent silent errors.