Index
Actors.AbsMinderActors.AbsStageActors.ActorActors.ActorActors.AsyncFail!Actors.Died!Actors.Genesis!Actors.IdActors.Invite!Actors.Invited!Actors.Leave!Actors.Left!Actors.LoggerActors.PreGenesis!Actors.SceneActors.Shout!Actors.StageActors.StoogeActors.TreeMinderActors.TroupeActors.askActors.asyncActors.capture_environmentActors.delegateActors.dieing_breath!Actors.enter!Actors.epilogue!Actors.expectActors.forkActors.hearActors.inboxActors.interact!Actors.interact!Actors.invite!Actors.leave!Actors.listen!Actors.local_addressesActors.meActors.minderActors.myActors.play!Actors.prologue!Actors.sayActors.shoutActors.shoutActors.stageActors.try_sayActors.@say_info
Reference
Actors.AbsMinder — TypeActors.AbsStage — TypeActors.Actor — TypeThe 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
SThe type of the user defined actor state.MThe 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.Actor — MethodCreate an Actor with the given state and minder
Actors.AsyncFail! — TypeInforms that an asynchronous Task failed
Members
async::TaskWhat failed
Actors.Died! — TypeInforms that an Actor died
Members
who::IdThe
Actorwho diedcorpse::Actors.ActorThe
Actorwho died's data
Actors.Genesis! — TypeSent to the users 'play' Actor to get things started
Members
Actors.Id — TypeThe 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.
This will grow in size as remote actors are added.
Type Parameters
SThe type of the actor state.MThe message types the actor accepts, usually Any.
Actors.Invite! — TypeActors.Invited! — TypeA response to Invite!
Actors.Leave! — TypeActors.Left! — TypeActors.Logger — TypeAn Actor which prints messages to an IO stream
By default one of these is created which writes to stdout exlusively.
Actors.PreGenesis! — TypeUsed by the Stage for bootstraping
Actors.Scene — TypeThe 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
Actors.Shout! — TypeWraps a message to broadcast (shout)
Actors.Stage — TypeThe 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.AddressBookAll the
Actors in the playtime_to_leave::Union{Nothing, Timer}Grace period timer before force leaving
play::IdUser defined play
Actor
Actors.Stooge — TypeActors.TreeMinder — TypeOrganises 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::Idminded::Union{Nothing, Id}children::Set{Id}
Actors.Troupe — TypeA 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 aTroupe
Actors.ask — MethodActors.async — MethodSimilar 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_environment — MethodUsed to capture variables from the parent thread/task
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.delegate — MethodActors.dieing_breath! — MethodActors.enter! — MethodActors.epilogue! — MethodActors.expect — MethodWait 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.fork — MethodCreate a new Task, Thread or similar primitive
Actors.hear — MethodHandle a received message
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.inbox — MethodGet 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! — MethodLike 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.
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!()
(Scene{Actors.Person}, Task (runnable) @0x00007fafc7dad600)
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, ..."
julia> local_addresses(s)
5-element Array{Pair{Int64,DataType},1}:
1 => Actors.Person
2 => Actors.Logger{Base.TTY}
3 => Actors.PassiveMinder{Id{Actors.Logger{Base.TTY},Union{Leave!, Actors.LogDied!, LogInfo!}}}
4 => Actors.InteractivePlay
5 => Ponger
Actors.interact! — MethodStart a minimal actor system which you can interact with from the REPL
Actors.invite! — MethodActors.leave! — MethodSignal that the current Actor should exit (leave)
Usually this closes the inbox which will cause the actor to exit once it has processed any messages it already received. Some actors (e.g Stage) have a grace period where they will continue to accept new messages.
If you wish to exit immediately then throw an exception.
Also see Leave!.
Actors.listen! — MethodTake 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.local_addresses — MethodActors.me — MethodActors.minder — MethodGet the address of an Actor's minder
When called on the Scene it will get the current Actor's minder. If called on an Id it will get the minder of the Actor pointed to by the address.
It is generally not thread-safe to change Actor.minder. However you can re-assign a minder's Id to another actor.
See AbsMinder.
Actors.my — MethodActors.play! — MethodStart 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:
Then, if there is an error
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.prologue! — MethodActors.say — MethodSend 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.shout — MethodBroadcast a message to a plain vector of actors
Actors.shout — MethodBroadcast a message to a Troupe
Actors.stage — MethodActors.try_say — MethodLike 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.
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.
Actors.@say_info — Macro