This page is a copy of the glossary writen by Tony Garnock-Jones from
the Synit manual.
Action
In the Syndicated Actor Model,
an action may be performed by an actor
during a turn. Actions are quasi-transactional,
taking effect only if their containing turn is committed.
Four core varieties of action, each with a matching variety of event, are offered across all realisations of the SAM:
An assertion action publishes an assertion at a target
entity. A unique [handle][] names the assertion action so that it
may later be retracted. For more detail, see below
on Assertions.
A retraction action withdraws a previously-published
assertion from the target entity.
A message action sends a message
to a target entity.
A synchronization action carries a local entity reference to a target entity. When it
eventually reaches the target, the target will (by default) immediately
reply with a simple acknowledgement to the entity reference carried in
the request. For more detail, see below on
Synchronization.
Beside the core four actions, many individual implementations offer
action variants such as the following:
A spawn action will, when the containing turn commits,
create a new actor running alongside the acting party. In many
implementations, spawned actors may optionally be linked to the spawning actor.
Replacement of a previously-established assertion,
“altering” the target entity reference and/or payload. This proceeds, conventionally, by
establishment of the new assertion followed immediately by retraction of
the old.
Finally, implementations may offer pseudo-actions whose effects are
local to the acting party:
The facet associated with the event currently being processed in an active turn.
Actor
In the Syndicated Actor Model,
an actor is an isolated thread of execution. An actor
repeatedly takes events from its mailbox, handling each in a turn. In many implementations of the SAM, each actor is internally
structured as a tree of facets.
verb. To assert (or to publish) a
value is to choose a target entity and perform an
action conveying an assertion to that
entity.
noun. An assertion is a value carried as the payload of an assertion action, denoting a relevant portion of a public
aspect of the conversational state of the sending party that it has
chosen to convey to the recipient entity.
The value carried in an assertion may, in some
implementations, depend on one or more dataflow variables; in those
implementations, when the contents of such a variable changes, the
assertion is automatically withdrawn, recomputed, and re-published (with
a fresh [handle][]).
Attenuation
To attenuate a capability
(yielding an attenuated capability), a sequence of filters is
prepended to the possibly-empty list of filters attached to an existing
capability. Each filter either discards, rewrites, or accepts unchanged
any payload directed at the underlying capability.
A special pattern language exists in the Syndicate network protocol for describing
filters; many implementations also allow in-memory capabilities to be
filtered by the same language.
Capability
(a.k.a. Cap) Used roughly interchangeably with “reference”, connoting a security-,
access-control-, or privacy-relevant aspect.
A method by which a utility performs some action and then uses
execve(2) to replace itself, similar to how a tail-call
replaces a stack frame. Usually the successor program is specified as
the tail of argv.
nice is an example of chain-loading utility that reduces
scheduling priority before starting another program. sudo
would be another example but in Synit chain-loading is seldom used to
escalate priviledge and mostly to reduce priviledge inherited from the
environment. In this way chain-loading is similar to referenceattenuation
in SAM.
The meaning of a complex expression is determined by its structure
and the meanings of its constituents.
People often implicitly intend “… and nothing else.” For
example, when I claim that the object-capability model is a
compositional approach to system security, I mean that the access
conveyed by an assemblage of capabilties can be understood in terms of
the access conveyed by each individual capability taken in isolation,
and nothing else.
The syndicate-server program includes a scripting
language, used for configuration of the server and its clients,
population of initial dataspaces for the system that the
syndicate-server instance is part of, and scripting of
simple behaviours in reaction to appearance of assertions or
transmission of messages.
The collection of facts and knowledge held by a component
participating in an ongoing conversation about some task that the
component is undertaking:
The conversational state that accumulates as part of a collaboration
among components can be thought of as a collection of facts. First,
there are those facts that define the frame of a conversation.
These are exactly the facts that identify the task at hand; we label
them “framing knowledge”, and taken together, they are the
“conversational frame” for the conversation whose purpose is completion
of a particular shared task. Just as tasks can be broken down into more
finely-focused subtasks, so can conversations be broken down into
sub-conversations. In these cases, part of the conversational state of
an overarching interaction will describe a frame for each
sub-conversation, within which corresponding sub-conversational state
exists. The knowledge framing a conversation acts as a bridge between it
and its wider context, defining its “purpose” in the sense of the
[Gricean Cooperative Principle]. [The following figure] schematically
depicts these relationships.
Figure 2 from Garnock-Jones
2017
Some facts define conversational frames, but every shared
fact is contextualized within some conversational frame. Within
a frame, then, some facts will pertain directly to the task at hand.
These, we label “domain knowledge”. Generally, such facts describe
global aspects of the common problem that remain valid as we shift our
perspective from participant to participant. Other facts describe the
knowledge or beliefs of particular components. These, we label
“epistemic knowledge”.
In the Syndicated Actor Model,
there is often a one-to-one correspondence between a facet and a conversational frame, with fate-sharing employed to connect the lifetime
of the one with the lifetime of the other.
Dataflow
A programming model in which changes in stored state automatically
cause re-evaluation of computations depending on that state. The results
of such re-evaluations are themselves often used to update a store,
potentially triggering further re-computation.
In the Syndicated Actor Model,
dataflow appears in two guises: first, at a coarse granularity, among
actors and entities in the form of changes in published assertions; and second, at fine granularity, many
implementations include dataflow
variables and dataflow blocks for
intra-actor dataflow-based management of conversational state and related
computation.
Dataflow Block
Implementations of the Syndicated
Actor Model often include some language feature or library operation
for marking a portion of code as participating in dataflow, where changes in observed dataflow variables cause re-evaluation of
the code block.
turn.dataflow(|turn| {
let a_value = turn.get(&a);
let b_value = turn.get(&b);
turn.set(&sum, a_value + b_value);
})
Dataflow Variable
(a.k.a. Field, Cell) A dataflow
variable is a store for a single value, used with dataflow blocks in dataflow programming.
When the value of a dataflow variable is read, the active dataflow block is marked as
depending on the variable; and when the value of the variable
is updated, the variable is marked as damaged, leading
eventually to re-evaluation of dataflow blocks depending on that
variable.
In the Syndicated Actor Model,
a dataspace pattern is a structured value
describing a pattern over other values. The pattern language used in
current Dataspace implementations and in the Syndicate protocol is
documented here.
Miller, Mark S. “Robust Composition: Towards a Unified Approach
to Access Control and Concurrency Control.” PhD, Johns Hopkins
University, 2006. [PDF]
Miller, Mark S., E. Dean Tribble, and Jonathan Shapiro.
“Concurrency Among Strangers.” In Proc. Int. Symp. on Trustworthy Global
Computing, 195–229. Edinburgh, Scotland, 2005. [DOI][PDF]
Concretely, in Preserves text
syntax, embedded values appear prepended with #:. In
messages transferred across links using the Syndicate network protocol, references
might appear as #:[0 123], #:[1 555], etc.
etc.
Entity
In the Syndicated Actor Model,
an entity is a stateful programming-language construct, located
within an actor, that is the target of events. Each entity has its own behaviour, specifying
in code how it responds to incoming events.
An entity is the SAM analogue of “object” in E-style
languages: an addressable construct logically contained within and fate-sharing with an actor. The concept of “entity” differs from “object”
in that entities are able to respond to assertions, not just messages.
In many implementations of the SAM, entities fate-share with individual facets within their containing actor rather than with
the actor as a whole: when the facet associated with an entity is
stopped, the entity becomes unresponsive.
Erlang
Erlang is a process-style Actor
language that has strongly influenced the Syndicated Actor Model. In
particular, Erlang’s approach to failure-handling, involving supervisors arranged in [supervision trees][] and
processes (actors) connected via links and
monitors, has been influential on the SAM. In the SAM, links and
monitors become special cases of assertions,
and Erlang’s approach to process supervision
is used directly and is an important aspect of SAM system
organisation.
Events come in four varieties corresponding to the four core actions in the SAM:
An assertion event notifies the recipient entity of an
assertion published by some peer. A unique
[handle][] names the event so that later retraction of the assertion can
be correlated with the assertion event.
A retraction event notifies the recipient entity of
withdrawal of a previously-published assertion.
A message event notifies the recipient entity of a message sent by some peer.
A synchronization event, usually not handled explicitly
by an entity, carries an entity reference. The
recipient should arrange for an acknowledgement to be delivered to the
referenced entity once previously-received events that might modify the
recipient’s state (or the state of a remote entity that it is proxy for)
have been completely processed. For more detail, see below on Synchronization.
execline
execline is a
collection of utilities for constructing scripts using chain-loading rather than a traditional shell
interpreter.
Every facet is either “running” or “stopped”. Each facet is the
logical owner of zero or more entities as well as
of zero or more published assertions. A facet’s
entities and published assertions share its
fate. While a facet is running, its associated entities are
responsive to incoming events; when it stops, its entities become
permanently unresponsive. A stopped facet never starts running again.
When a facet is stopped, all its assertions are retracted and all its
subfacets are also stopped.
Facets may have stop handlers associated with them: when a
facet is stopped, its stop handlers are executed, one at a time. The
stop handlers of each facet are executed before the stop handlers of its
parent and before its assertions are withdrawn.
Facets may be explicitly stopped by a stop action, or implicitly stopped when an actor crashes.
When an actor crashes, its stop handlers are not run: stop handlers are
for orderly processing of conversation termination. Instead, many
implementations allow actors to have associated crash handlers
which run only in case of an actor crash. In the limit, of course, even
crash handlers cannot be guaranteed to run, because the underlying
hardware or operating system may suffer some kind of catastrophic
failure.
Fate-sharing
A design principle from large-scale network engineering, due to David
Clark:
The fate-sharing model suggests that it is acceptable to lose the
state information associated with an entity if, at the same time, the
entity itself is lost.
— David D. Clark, “The Design Philosophy of the DARPA Internet
Protocols.” ACM SIGCOMM Computer Communication Review 18, no. 4 (August
1988): 106–14. [DOI]
In the Syndicated Actor Model,
every assertionaction
(and the corresponding event) includes a scope-lifetime-unique handle that denotes the
specific action/event concerned, for purposes of later correlation with
a retraction action.
Handles are, in many cases, implemented as unsigned integers,
allocated using a simple scope-wide counter.
Initial OID
In the Syndicate network protocol,
the initial OID is a special OID value understood by
prior arrangement to denote an entity (specified
by the “initial ref”) owned by some remote
peer across some network medium. The initial OID of a session is used to
bootstrap activity within that session.
Many implementations of the Syndicated Actor Model offer a
feature whereby an actor can be spawned so that its
root facet is linked to the spawning facet
in the spawning actor, so that when one terminates, so does the other
(by default).
Links are implemented as a pair of “presence” assertions, atomically established at the time of
the spawn action, each indicating to a special
entity with “stop on retraction” behaviour the presence of its peer.
When one of these assertions is withdrawn, the targetted entity stops
its associated facet, automatically terminating any
subfacets and executing any stop handlers.
This allows a “parent” actor to react to termination of its child,
perhaps releasing associated resources, and the corresponding “child”
actor to be automatically terminated when the facet in its parent that
spawned the actor terminates.
This idea is inspired by Erlang, whose “links”
are symmetric, bidirectional, failure-propagating connections among
Erlang processes (actors) and whose “monitors”
are unidirectional connections similar to the individual “presence”
assertions described above.
Linked Task
Many implementations of the Syndicated Actor Model offer the
ability to associate a facet with zero or more native threads,
coroutines, objects, or other language-specific representations of
asynchronous activities. When such a facet stops (either by explicit stop action or by crash-termination of the facet’s
actor), its linked tasks are also terminated. By default, the converse
is also the case: a terminating linked task will trigger termination of
its associated facet. This allows for resource management patterns
similar to those enabled by the related idea of linked actors.
Macaroon
A macaroon is an access token for authorization of actions
in distributed systems. Macaroons were introduced in the paper:
In the Syndicated Actor Model,
a variation of the macaroon concept is used to represent “sturdyrefs”. A
sturdyref is
a long-lived token authorizing interaction with some entity, which can
be upgraded to a live entity reference by
presenting it to a gatekeeper entity across a
session of the Syndicate network
protocol. (The term “sturdyref” is lifted directly from the E language and associated ecosystem.)
Mailbox
Every actor notionally has a mailbox
which receives events resulting from its peers’ actions. Each actor spends its existence waiting for
an incoming event to appear in its mailbox, removing the event, taking a
turn to process it, and repeating the cycle.
In the Syndicated Actor Model,
a message is a value carried as the
payload or body of a message action (and
associated event), conveying transient information
from some sending actor to a recipient entity.
Network
A network is a group of peers (actors), plus a
medium of communication (a transport), an
addressing model (references), and an
associated scope.
Object-Capability Model
The Object-capability
model is a compositional means of expressing access control in a
distributed system. It has its roots in operating systems research
stretching back decades, but was pioneered in a programming language
setting by the E language and the Scheme dialect W7.
Each Observe record contains a dataspace pattern describing a structural
predicate over assertion and message payloads, plus
an entity reference to the entity which should be informed as matching events
appear at the dataspace.
Many implementations of the SAM
use Preserves, a programming-language-independent language for
data, as the language defining the possible values
that may be exchanged among entities in assertions and values.
The Preserves data language defines the
notion of a record, a tuple containing a label and
zero or more numbered fields. The dataspace pattern language used by dataspaces allows for patterns over records as
well as over other compound data structures.
Reference
(a.k.a. Ref, Entity Reference,
Capability) A
reference is a pointer or handle denoting a live, stateful entity running within an actor.
The entity accepts Preserves-format messages and/or assertions.
The capability may be attenuated to restrict
the messages and assertions that may be delivered to the denoted entity
by way of this particular reference.
Retraction
In the Syndicated Actor Model,
a retraction is an action (and
corresponding event) which withdraws a previous assertion. Retractions can be explicitly performed
within a turn, or implicitly performed during facet shutdown or actor
termination (both normal termination and crash stop).
The SAM guarantees that an
actor’s assertions will be retracted when it terminates, no matter
whether an orderly shutdown or an exceptional or crashing situation was
the cause.
A relay entity is a local proxy for an entity at the other side of a relay link. It forwards events
delivered to it across its transport to its
counterpart at the other end.
a small suite of programs for UNIX, designed to allow process supervision (a.k.a service supervision), in the
line of daemontools and runit, as well as various operations on
processes and daemons.
A schema defines a mapping between values and host-language types in various programming
languages. The mapping describes how to parse values into host-language
data, as well as how to unparse host-language data, generating
equivalent values. Another way of thinking about a schema is as a
specification of the allowable shapes for data to be used in a
particular context.
Most actors will participate in a single scope.
However, relay actors participate in two or more
scopes, translating refs back and forth as messages and assertions
traverse the relay.
Examples.
A process is a scope for in-memory values: in-memory refs contain
direct pointers to entities, which cannot be interpreted outside the
context of the process’s address space. The “network” associated with
the process’s scope is the intra-process graph of object
references.
A TCP/IP socket (or serial link, or WebSocket, or Unix socket,
etc.) is a scope for values travelling between two connected processes:
refs on the wire denote entities owned by one
or the other of the two participants. The “network” for a socket’s scope
is exactly the two connected peers (NB. and is not the
underlying TCP/IP network, HTTP network, or Unix kernel that supports
the point-to-point link).
An ethernet segment is a scope for values broadcast among
stations: the embedded refs are (MAC address, OID)
pairs. The network is the set of participating peers.
A running web page is a scope for the JavaScript objects it
contains: both local and remote entities are represented by JavaScript
objects. The “network” is the JavaScript heap.
Subscription
See observation. ## Supervision tree
[Supervision trees]: #supervision-tree [Supervision tree]:
#supervision-tree
A supervision tree is a concept borrowed from Erlang, where a root supervisor supervises other supervisors, which in
turn supervise worker actors engaged in some task.
As workers fail, their supervisors restart them; if the failures are too
severe or too frequent, their direct supervisors fail in turn, and the
supervisors’ supervisors take action to recover from the failures.
Supervisor
A supervisor is an actor or facet whose role is to monitor the state of some
service, taking action to ensure its availability to other portions of a
complete system. When the service fails, the supervisor is able to
restart it. If the failures are too severe or too frequent, the
supervisor can take an alternative action, perhaps pausing for some time
before retrying the service, or perhaps even terminating itself to give
its own supervisor in a [supervision tree][] a chance to get things back
on track.
Synit uses supervisors extensively to monitor system daemons and
other system services.
An actor may synchronize with an entity by scheduling a synchronizationaction targeted at that entity. The action will carry
a local entity reference acting as a
continuation. When the target entity eventually responds, it will
transmit an acknowledgement to the continuation entity reference carried
in the request.
An entity receiving a synchronization event
should arrange for an acknowledgement to be delivered to the referenced
continuation entity once previously-received events that might modify
the recipient’s state (or the state of a remote entity that it is proxy
for) have been completely processed.
Most entities do not explicitly include code for responding to
synchronization requests. The default code, which simply replies to the
continuation immediately, usually suffices. However, sometimes the
default is not appropriate. For example, when relay entity is proxying for some remote entity
via a relay across a transport, it should react to synchronization
events by forwarding them to the remote entity. When the remote entity
receives the forwarded request, it will reply to its local proxy for the
continuation entity, which will in turn forward the reply back across
the transport.
The Syndicated Actor Model (often abbreviated
SAM) is the model of concurrency and communication
underpinning Synit. The SAM offers a “conversational” metaphor: programs
meet and converse in virtual locations, building common understanding of
the state of their shared tasks.
In the SAM, source entities running within an
actor publish assertions
and send messages to target entities, possibly in
other actors. The essential idea of the SAM is that state replication is
more useful than message-passing; message-passing protocols often end up
simulating state replication.
The system layer is an
essential part of an operating system, mediating between user-facing
programs and the kernel. It provides the technical foundation for many
qualities relevant to system security, resilience, connectivity,
maintainability and usability.
The hypothesis that the Synit system explores is that the Syndicated Actor model provides a
suitable theoretical and practical foundation for a system layer. The
system layer demands, and the SAM supplies, well-integrated expression
of features such as service naming, presence, discovery and activation;
security mechanism and policy; subsystem isolation; and robust handling
of partial failure.
System Dataspace
The system dataspace in Synit is the primary dataspace
entity, owned by an actor running within the root system
bus, and (selectively) made available to daemons, system services,
and user programs.
Timeout
Many implementations of the Syndicated Actor Model offer actions for establishing timeouts,
i.e. one-off or repeating alarms. Timeouts are frequently implemented as
linked tasks.
Transport
A transport is the underlying medium connecting one relay to its counterpart(s) in an instance of the Syndicate network protocol. For example,
a TLS-on-TCP/IP socket may connect a pair of relays to one another, or a
UDP multicast socket may connect an entire group of relays across an
ethernet.
Turn
Each time an event arrives at an actor’s mailbox, the actor
takes a turn. A turn is the process of handling the triggering
event, from the moment of its withdrawal from the mailbox to the moment
of the completion of its interpretation.
Relatedly, the programming-language representation of a turn
is a convenient place to attach the APIs necessary for working with the
Syndicated Actor Model. In many
implementations, some class named Turn or similar exposes
methods corresponding to the actions available in
the SAM.
the collection of pending actions produced
during execution.
If a turn proceeds to completion without an exception or other crash,
its pending actions are committed (finalised and/or delivered
to their target entities). If, on the other hand, the turn is aborted
for some reason, its pending actions are rolled back
(discarded), the actor is terminated, its assertions retracted, and all its resources released.
Value
A PreservesValue with embedded
data. The embedded data are often embedded references but, in some
implementations, may be other kinds of datum. Every message body and every assertion payload is a value.
Wire Symbol
A wire symbol is a structure used in implementations of the
Syndicate network protocol to maintain
a connection between an in-memory entity
reference and the equivalent name for the entity as used in packets
sent across the network.