6.0.0.1
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,
and
topics are ordinary Racket values which may have embedded
wildcards.
Each time
? (or
(wild)) is used in an expression
context, it produces a fresh topic wildcard, suitable for use in a
topic pattern.
Roles are almost always constructed by the
endpoint/
endpoint: macros or by the VM
implementations themselves. User programs generally only need to
destructure
role instances.
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
'publisher) tend to use
send-message and tend to
respond to feedback from subscribers; subscribers
(
'subscriber) tend to use
send-feedback and respond
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
its topic.
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
observer endpoints.
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
match.
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
interest-type.
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
handler’s
endpoint.
3.4 Actions
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.
An
at-meta-level 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 is invoked.
3.4.1 Endpoints and Messages
Creates a new endpoint subscribing to the given
Role. When
events pertaining to the given role occur, the
Handler is
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
reason is passed along to peer endpoints as part of an
absence-event.
If no specific reason is needed, it is conventional to supply
#f as the delete-endpoint-reason. See also the
convenience delete-endpoint
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
be
'publisher, but when the message is
feedback for
some publisher, it will be
'subscriber.
See also the
send-message and
send-feedback convenience functions from
marketplace/sugar-values.
3.4.2 Process Management
A
spawn requests the creation of a sibling process
If
wrapped in an at-meta-level, the new process will instead be
a sibling of the creating process’s VM.. The
spawn-k runs in
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
approach.
Kills a sibling process.
Or, if at-meta-level, a sibling
process of the containing VM. If
quit-pid is
#f,
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
absence-event, 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.