3 Low-level interface
At its heart, the interface between each process and its
containing VM is based on handler functions exchanging
event and action structures with the VM. Both events and
actions are simple Racket structures.
This low-level interface between a VM and a process is analogous to
the system call interface of a Unix-like operating system. The
High-level interface corresponds to the C library
interface of a Unix-like operating system.
3.1 Handler Functions
Each handler function is always associated with a particular
endpoint, registered with the VM via
endpoint/endpoint:/add-endpoint. A handler
function for a given process with state type State has type:
(EndpointEvent -> State -> (Transition State))
That is, given an EndpointEvent followed by the process’s
current state, the handler should reply with a Transition
containing a new process state and a collection of Actions.
Typed Racket types capturing various notions of handler function.
3.2 Messages, Topics and Roles
As previously mentioned, messages
are ordinary Racket values,
are ordinary Racket values which may have embedded
Each time ?
) is used in an expression
context, it produces a fresh topic wildcard, suitable for use in a
Roles are almost always constructed by the
macros or by the VM
implementations themselves. User programs generally only need to
A role describes the conversational role of a peer as seen by
some process. For example, a subscriber to topic 'foo with
interest-type 'participant might receive a presence
notification carrying the role
(role 'publisher 'foo 'participant)
Notice that the orientation of the role is the opposite of the
orientation of the endpoint.
Describes an endpoint’s orientation: will it be acting as a publisher
of messages, or as a subscriber to messages? Publishers (orientation
) tend to use send-message
and tend to
respond to feedback from subscribers; subscribers
) tend to use send-feedback
to messages from publishers.
Using interest-type 'participant in an endpoint’s role
indicates that the endpoint is intending to act as a genuine
participant in whatever protocol is associated with the endpoint and
Using 'observer indicates that the endpoint is intended to
monitor other ongoing (participant) conversations instead.
Observer endpoints receive presence and absence notifications about
participant endpoints, but participant endpoints only receive
notifications about other participant endpoints, and not about
The 'observer interest-type is intended to make it easier to
monitor resource demand and supply. The monitoring endpoints/processes
can react to changing demand by creating or destroying resources to
Finally, the 'everything interest-type receives notifications
about presence and absence of all the types of endpoint,
'participant, 'observer, and 'everything.
Endpoints with interest-type 'everything are rare: they are
relevant for managing demand for observers, as well as in some
cases of cross-layer presence/absence propagation. Most programs (and
even most drivers) will not need to use the 'everything
3.3 Endpoint Events
Endpoint events are passed to handler functions by VMs, conveying some
change in the world the process lives in. An endpoint event can signal
the arrival or departure of a conversational peer, or can deliver a
message that has been sent on a VM’s IPC facility.
Indicates the arrival of a new conversational partner: an endpoint
with a topic that intersects our own, with Orientation
opposite to our own.
The presence-event-role describes the arriving peer, or more
precisely, describes the shared interest between ourselves and the new
peer. In particular, the role-orientation of the
presence-event-role is the orientation that the peer
supplied in its add-endpoint structure.
Indicates the departure of an existing conversational partner, through
either an explicit delete-endpoint
action or the implicit
deleting of all of a process’s endpoints when a process exits.
The absence-event-role describes the departing peer,
analogously to presence-event-role.
Indicates the arrival of a message matching the topic pattern in the
Actions are requests from a process to its containing VM. If wrapped
in an at-meta-level
structure, the action is to apply to
the VM’s own containing VM
; otherwise, the action applies to
the process’s containing VM.
structure wraps a plain action, and makes it
apply to the outer VM instead of the inner VM (the default).
Because current VM implementations are cooperatively scheduled, it can
sometimes be necessary to explicitly yield the CPU to other processes
using a yield
action. When control returns to the yielding
process, the yield-k
3.4.1 Endpoints and Messages
Creates a new endpoint subscribing to the given Role
events pertaining to the given role occur, the Handler
invoked.If invoked at-meta-level, subscribes to events
in the containing VM’s container.
The name of the new endpoint will be the pre-eid; it must be
unique within the current process, but otherwise can be any value at
all. If the endpoint’s name matches an existing endpoint, and the new
role is the same as the existing endpoint’s role, the handler function
is replaced in the existing endpoint.
To delete an endpoint, perform a delete-endpoint action built
with the name of the endpoint to delete.
Deletes an existing endpoint named pre-eid
. The given
is passed along to peer endpoints as part of an
If no specific reason is needed, it is conventional to supply
#f as the delete-endpoint-reason. See also the
function from marketplace/sugar-values.
Sends a message to peers.Or, if at-meta-level, peers of
the containing VM.
The given Orientation
should describe the
role the sender is playing when sending this message: usually, it will
, but when the message is feedback
some publisher, it will be 'subscriber
See also the send-message
convenience functions from
3.4.2 Process Management
requests the creation of a sibling processIf
wrapped in an at-meta-level, the new process will instead be
a sibling of the creating process’s VM.
. The spawn-k
the context of the creating
process, communicating to it the
PID of the new process.
The spawn-spec describes the new process to be created. Its
process-spec-boot field is a function taking the PID of the
new process and returning a "cotransition". Cotransitions use a
second-order encoding of existential types to guarantee that the VM
remains oblivious to the specific process state type of the new
process. The downside of this approach is its syntactic and type
complexity: see spawn: for an easier-to-use, higher-level
Kills a sibling process.Or, if at-meta-level, a sibling
process of the containing VM.
kills the current process; otherwise, kills the process with the given
PID. The quit-reason
is passed on to peers of
currently-active endpoints in the process to be killed, as part of a
, just as if each active endpoint were deleted
manually before the process exited.
If no specific reason is needed, it is conventional to supply
#f as the quit-reason.
In the current VM implementations, process IDs are simply numbers.
PIDs are scoped to and allocated by each individual VM instance.