Misty has direct support for actors. Actors run independently and concurrently. Actors communicate by sending messages. Every actor has its own memory space. Actors do not share memory. A program is generally a lead actor that may be supported by a team of supporting actors running in the same machine or in different machines. An actor may make use of modules.
misty
"misty"
space misty_type space name '{'
indent use statements outdent '}'
misty_type
"actor"
"module"
Every actor has an actor object called @
at sign that contains a reference to the actor itself and other powerful capabilities. An actor can pass actor objects (including an attenuated version of @
) as parameters to functions or in messages to other actors. If an actor can acquire the actor object of another actor, then it can send messages to it. Messages may contain numbers, texts, records, arrays, logicals, null
, blobs, and actor objects.
An attenutated @
object is produced when @
is on the right side of a set
statement, or when @
is passed an argument to a function, or wehn @
is included in an array literal or record literal..
Misty programs are organized into source files. There are two types of Misty source files:
A module is a chunk of independent program. These can be used to build reusable libraries. The last statement in a module is a return
statement, which usually returns a function or a record containing functions. That return value is bound to the name in a use
statement.
An actor file includes the word actor
before the name.
In this example, the example
actor imports the app_master_2000
module, and designates its handler
function as the receiver of messages for the actor.
misty actor example { use app: "app_master_2000" call @.receiver(app.handler) }
Actors are started with the @.new
method. An actor that starts another actor is call a master. An actor started by a master is called a padawan. An actor can be a padawan to one actor and a master to many others.
Communication between actors happens exclusively with messages. Messages are one way with eventual consequences.
Messages are usually transmitted over some sort of connection.
use
statementuse
""
"use"
space name locator linebreak use
locator
""
": "
text
The use statement makes a module available to an actor or other module. The return value of the module is bound to the name. An optional locator can be provided for finding the module file. Standard modules do not require a locator.
An actor object contains the information needed to communicate with an actor. An actor object can be transmitted to other actors, even on other machines.
An actor object is an immutable black box. It can be used in a send
statement to send a message to the actor associated with the actor object. Actor objects can be sent to other actors, giving them the capability to also send messages to the actor associated with the actor object.
None of the contents of the actor object are visible or accessible.
Example:
actor?(@) # true actor?(my_actor) # true record?(my_actor) # false stone?(my_actor) # true my_actor = my_actor # true my_actor = your_actor # false (probably)
actor?
functionThe actor?
function gives true
if the value is an actor object.
Actors communicate using messages. Actors do not share variables or functions.
Incoming messages are queued by the Misty system and delivered in arrival order. The exceptions are system level messages like the die
message, which, if valid, will cause an actor to immediately fail, even if there are undelivered messages waiting for it in the queue.
Some messages can be used to reply to the original sender of the message.
The receiver
method is given a callback function that will receive the actor's messages. The callback function will receive a single argument, the message object.
The Misty System uses its own messaging system to transmit system messages. A system message type has ℠
as its first character. Reserved ℠
messages can not be sent by the send
statement.
The begin
message is the first message sent to an actor when it is created. It will contain the actor object of the master.
The end
message is sent when an actor is no longer needed. The actor receiving this message should finish its work and die
.
The die
message is not queued or delivered to the actor. Instead, the actor is immediately terminated. It will also terminate the novices and pact actors. The die
message can only be sent by the die
method or as a consequence of a pact.
The done
message is sent to the master of an actor if an actor stops for any reason.
The hello
message is sent as a response to the contact
method. It will include the actor object of the remote actor.
The pact
message is a request to be sent a die
message when the receiver dies.
@
MethodsThe @
object is only available in the misty
actor
files. The @
object is not available in misty
module
files, although the attenuated actor object and some of the @
methods can be passed in. The @
object may contain these methods: new
, connection
, contact
, receiver
, portal
, kill
, pact
, delay
, clock
, random
.
new
methodThe new
function creates a new actor. It takes a text that identifies the actor program file that the new actor runs. It sends the ℠begin
message to the new actor.
The configuration record contains fields having the names of the @
methods. If the field's value is true
, then the new actor will have that method in its own @
object. So, if the configuration contains a contact
field that is true
, then the new actor is allowed to contact portals to obtain actor objects.
The callback is passed the new actor object.
Example:
call @.actor.new( callback, "example.mst", { contact: true, new: true, pact: true, receiver: true } )
connection
methodThe connection
method takes a callback function, an actor object, and a configuration record for getting information about the status of a connection to an actor. The configuration record is used to request the sort of information that needs to be communicated. This can include partitions, speed, congestion, cost, activity. The callback will be given a record containing the requested information.
contact
methodThe contact
method sends a message to a portal on another machine to obtain an actor object.
The record can contain:
The current actor is the parent of the new actor, and it will be notified when the new actor terminates.
The callback function will be passed the padawan actor object.
receiver
methodThis method registers a function that will receive all messages sent to the actor except for portal contact messages, and replies.
portal
methodA portal is a special actor that that performs introduction services. It listens on a specified port for contacts by external actors that need to acquire an actor object. The function will receive the record containing the request. The record can have a reply sent through it. A portal can respond by beginning a new actor, or finding an existing actor, or by forwarding the contact message to another actor. This is how distributed Misty networks are bootstrapped.
kill
methodThis method sends the die
message. The actor object must be one of your own novices or @
. An actor may kill itself.
pact
methodThe pact function links two actors together in a suicide pact. If the other actor object fails, then actor object will fail. The actor object must be either @
or one of its padawans.
If a master fails, then all of its padawans fail automatically.
delay
method@.delay(
function,
seconds)
The delay
function is used to schedule the invocation of a function at a later time. Any value returned
from the delayed invocation will be ignored. There is no guarentee that the function will ever be invoked. The delayed invocation will not interrupt
normal processing. The invocation will be delayed until the system is
quiescent.
The delay
function immediately returns a cancel function. Calling the cancel function will cancel the delayed execution of the function, if it is not too late..
The seconds parameter determines when the invocation will occur,
no sooner than seconds seconds after now. The seconds parameter must be a non-negative number or null
which behaves as 0.
clock
method@.clock(function)
The clock
method takes a function argument that will eventually be called with the current time
in number form. See time.
The random
function returns a number between 0 and 1.
An actor object is used with the send
statement. It contains the address of an actor. A message may contain actor objects, which will give the recipient actor the capability to send to those actors.
There are three ways that an actor can obtain an actor object of another actor:
@.new
@.contact
A message object is obtained from the callback function that is registered with @.receiver
. It acts like an ordinary record.
When a message is sent using the callback form, the message may be used as an actor object for transmitting the reply.
Computation takes place in an actor in a fragment of time called a turn. A turn starts with the delivery of a message or delay. A function (such as the function registered with @.receive
, @.portal
, @.clock
, or a @.delay
callback function) will run to completion or failure. Any outgoing messages will be held until the turn completes successfully, at which time they go into the outgoing queue and are sent.
An actor will not receive another message until the turn ends. Each turn will process exactly one message.
If a machine has multiple computation units, then it is possible for multiple turns of multiple actors to be going on simultaneously. Turns can be timesliced. There are no concurrency issues because actors do not share memory. They communicate with other actors and the world only by message passing.