@ -155,8 +155,8 @@
;;; Here's an image to get started:
;;;
;;; .----------------------------------. .-------------------.
;;; | Machine 1 | | Machine 2 |
;;; | ========= | | ========= |
;;; | Node 1 | | Node 2 |
;;; | ====== | | ====== |
;;; | | | |
;;; | .--------------. .---------. .-. .-. |
;;; | | Vat A | | Vat B | | \______| \_ .----------. |
@ -185,21 +185,21 @@
;;; Alfred are both objects in Vat A, Bob is an object in Vat B, and
;;; Carol and Carlos are objects in Vat C.
;;;
;;; - Zooming out the farthest is the "machi ne/network level".
;;; There are two machines (Machine 1 and Machine 2) connected over a
;;; Goblins CapTP network. The stubby shapes on the borders between the
;;; machines represent the directions of references Machin e 1 has to
;;; objects in Machine 2 (at the top) and references Machin e 2 has to
;;; Machine 1. Both machin es in this diagram are cooperating to preserve
;;; - Zooming out the farthest is the "nod e/network level".
;;; There are two nodes (Node 1 and Node 2) connected over CapTP network.
;;; The stubby shapes on the borders between the
;;; nodes represent the directions of references Nod e 1 has to
;;; objects in Node 2 (at the top) and references Nod e 2 has to
;;; Node 1. Both nod es in this diagram are cooperating to preserve
;;; that Bob has access to Carol but that Carol does not have access to
;;; Bob, and that Carlos has access to Bob but Bob does not have access
;;; to Carlos. (However there is no strict guarantee from either
;;; machi ne's perspective that this is the case... generally it's in
;;; nod e's perspective that this is the case... generally it's in
;;; everyone's best interests to take a "principle of least authority"
;;; approach though so usually it is.)
;;;
;;; This illustration is what's sometimes called a "grannovetter diagram"
;;; in the oc ap community, inspired by the kinds of diagrams in Mark
;;; in the OC ap community, inspired by the kinds of diagrams in Mark
;;; S. Grannovetter's "The Strength of Weak Ties" paper. The connection is
;;; that while the "Weak Ties" paper was describing the kinds of social
;;; connections between people (Alice knows Bob, Bob knows Carol), similar
@ -215,143 +215,143 @@
;;;
;;; Generally, things look like so:
;;;
;;; (machi ne (vat (actormap {refr: (mactor object-handler)})))
;;; (nod e (vat (actormap {refr: (mactor object-handler)})))
;;;
;;; However, we could really benefit from looking at those in more detail,
;;; so from the outermost layer in...
;;;
;;; .--- A machi ne in Goblins is basically an OS process.
;;; .--- A nod e in Goblins is basically an OS process.
;;; | However, the broader Goblins CapTP/MachineTP network is
;;; | made up of many machi nes. A connection to another machi ne
;;; | is the closest amount of "assurance" a Goblins machi ne has
;;; | made up of many nod es. A connection to another nod e
;;; | is the closest amount of "assurance" a Goblins nod e has
;;; | that it is delivering to a specific destination.
;;; | Nonetheless, Goblins users generally operate at the object
;;; | reference level of abstraction, even across machi nes.
;;; | reference level of abstraction, even across nod es.
;;; |
;;; | An object reference on the same machi ne is considered
;;; | "local" and an object reference on another machi ne is
;;; | An object reference on the same nod e is considered
;;; | "local" and an object reference on another nod e is
;;; | considered "remote".
;;; |
;;; | .--- Chris: "How about I call this 'hive'?"
;;; | | Ocap community: "We hate that, use 'vat'"
;;; | | Everyone else: "What's a 'vat' what a weird name"
;;; | |
;;; | | A vat is a traditional ocap term, both a container for
;;; | | objects but most importantly an event loop that
;;; | | communicates with other event loops. Vats operate
;;; | | "one turn at a time"... a toplevel message is handled
;;; | | for some object which is transactional; either it happens
;;; | | or, if something bad happens in-between, no effects occur
;;; | | at all (except that a promise waiting for the result of
;;; | | this turn is broken).
;;; | |
;;; | | Objects in the same vat are "near", whereas objects in
;;; | | remote vats are "far". (As you may notice, "near" objects
;;; | | can be "near" or "far", but "remote" objects are always
;;; | | "far".)
;;; | |
;;; | | This distinction is important, because Goblins supports
;;; | | both asynchronous messages + promises via `<-` and
;;; | | classic synchronous call-and-return invocations via `$`.
;;; | | However, while any actor can call any other actor via
;;; | | <-, only near actors may use $ for synchronous call-retun
;;; | | invocations. In the general case, a turn starts by
;;; | | delivering to an actor in some vat a message passed with <-,
;;; | | but during that turn many other near actors may be called
;;; | | with $. For example, this allows for implementing transactional
;;; | | actions as transferring money from one account/purse to another
;;; | | with $ in the same vat very easily, while knowing that if
;;; | | something bad happens in this transaction, no actor state
;;; | | changes will be committed (though listeners waiting for
;;; | | the result of its transaction will be informed of its failure);
;;; | | ie, the financial system will not end up in a corrupt state.
;;; | | In this example, it is possible for users all over the network
;;; | | to hold and use purses in this vat, even though this vat is
;;; | | responsible for money transfer between those purses.
;;; | | For an example of such a financial system in E, see
;;; | | "An Ode to the Grannovetter Diagram":
;;; | | http://erights.org/elib/capability/ode/index.html
;;; | |
;;; | | .--- Earlier we said that vats are both an event loop and
;;; | | | a container for storing actor state. Surprise! The
;;; | | | vat is actually wrapping the container, which is called
;;; | | | an "actormap". While vats do not expose their actormaps,
;;; | | | Goblins has made a novel change by allowing actormaps to
;;; | | | be used as independent first-class objects. Most users
;;; | | | will rarely do this, but first-class usage of actormaps
;;; | | | is still useful if integrating Goblins with an existing
;;; | | | event loop (such as one for a video game or a GUI) or for
;;; | | | writing unit tests.
;;; | | |
;;; | | | The keys to actormaps are references (called "refrs")
;;; | | | and the values are current behavior. This is described
;;; | | | below.
;;; | | |
;;; | | | Actormaps also technically operate on "turns", which are
;;; | | | a transactional operation. Once a turn begins, a dynamic
;;; | | | "syscaller" (or "actor context") is initialized so that
;;; | | | actors can make changes within this transaction. At the
;;; | | | end of the turn, the user of actormap-turn is presented
;;; | | | with the transactional actormap (called "transactormap")
;;; | | | which can either be committed or not to the current mutable
;;; | | | actormap state ("whactormap", which stands for
;;; | | | "weak hash actormap"), alongside a queue of messages that
;;; | | | were scheduled to be run from actors in this turn using <-,
;;; | | | and the result of the computation run.
;;; | | |
;;; | | | However, few users will operate using actormap-turn directly,
;;; | | | and will instead either use actormap-poke! (which automatically
;;; | | | commits the transaction if it succeeds or propagates the error)
;;; | | | or actormap-peek (which returns the result but throws away the
;;; | | | transaction; useful for getting a sense of what's going on
;;; | | | without committing any changes to actor state).
;;; | | | Or, even more commonly, they'll just use a vat and never think
;;; | | | about actormaps at all.
;;; | | |
;;; | | | .--- A reference to an object or actor.
;;; | | | | Traditionally called a "ref" by the ocap community, but
;;; | | | | scheme already uses "-ref" everywhere so we call it
;;; | | | | "refr" instead. Whatever.
;;; | | | |
;;; | | | | Anyway, these are the real "capabilities" of Goblins'
;;; | | | | "object capability system". Holding onto one gives you
;;; | | | | authority to make invocations with <- or $, and can be
;;; | | | | passed around to procedure or actor invocations.
;;; | | | | Effectively the "moral equivalent" of a procedure
;;; | | | | reference. If you have it, you can use (and share) it;
;;; | | | | if not, you can't.
;;; | | | |
;;; | | | | Actually, technically these are local-live-refrs...
;;; | | | | see "The World of Refrs" below for the rest of them.
;;; | | | |
;;; | | | | .--- We're now at the "object behavior" side of
;;; | | | | | things. I wish I could avoid talking about
;;; | | | | | "mactors" but we're talking about the actual
;;; | | | | | implementation here so... "mactor" stands for
;;; | | | | | "meta-actor", and really there are a few
;;; | | | | | "core kinds of behavior" (mainly for promises
;;; | | | | | vs object behavior). But in the general case,
;;; | | | | | most objects from a user's perspective are the
;;; | | | | | mactor:object kind, which is just a wrapper
;;; | | | | | around the current object handler (as well as
;;; | | | | | some information to track when this object is
;;; | | | | | "becoming" another kind of object.
;;; | | | | |
;;; | | | | | .--- Finally, "object"... a term that is
;;; | | | | | | unambiguous and well-understood! Well,
;;; | | | | | | "object" in our system means "references
;;; | | | | | | mapping to an encapsulation of state".
;;; | | | | | | Refrs are the reference part, so
;;; | | | | | | object-handlers are the "current state"
;;; | | | | | | part. The time when an object transitions
;;; | | | | | | from "one" behavior to another is when it
;;; | | | | | | returns a new handler wrapped in a "become"
;;; | | | | | | wrapper specific to this object (and
;;; | | | | | | provided to the object at construction
;;; | | | | | | time)
;;; | | | | | |
;;; V V V V V V
;;; (machi ne (vat (actormap {refr: (mactor object-handler)})))
;;; | .-- --- Christine : "How about I call this 'hive'?"
;;; | | Ocap community: "We hate that, use 'vat'"
;;; | | Everyone else: "What's a 'vat' what a weird name"
;;; | |
;;; | | A vat is a traditional ocap term, both a container for
;;; | | objects but most importantly an event loop that
;;; | | communicates with other event loops. Vats operate
;;; | | "one turn at a time"... a toplevel message is handled
;;; | | for some object which is transactional; either it happens
;;; | | or, if something bad happens in-between, no effects occur
;;; | | at all (except that a promise waiting for the result of
;;; | | this turn is broken).
;;; | |
;;; | | Objects in the same vat are "near", whereas objects in
;;; | | remote vats are "far". (As you may notice, "near" objects
;;; | | can be "near" or "far", but "remote" objects are always
;;; | | "far".)
;;; | |
;;; | | This distinction is important, because Goblins supports
;;; | | both asynchronous messages + promises via `<-` and
;;; | | classic synchronous call-and-return invocations via `$`.
;;; | | However, while any actor can call any other actor via
;;; | | <-, only near actors may use $ for synchronous call-retun
;;; | | invocations. In the general case, a turn starts by
;;; | | delivering to an actor in some vat a message passed with <-,
;;; | | but during that turn many other near actors may be called
;;; | | with $. For example, this allows for implementing transactional
;;; | | actions as transferring money from one account/purse to another
;;; | | with $ in the same vat very easily, while knowing that if
;;; | | something bad happens in this transaction, no actor state
;;; | | changes will be committed (though listeners waiting for
;;; | | the result of its transaction will be informed of its failure);
;;; | | ie, the financial system will not end up in a corrupt state.
;;; | | In this example, it is possible for users all over the network
;;; | | to hold and use purses in this vat, even though this vat is
;;; | | responsible for money transfer between those purses.
;;; | | For an example of such a financial system in E, see
;;; | | "An Ode to the Grannovetter Diagram":
;;; | | http://erights.org/elib/capability/ode/index.html
;;; | |
;;; | | .--- Earlier we said that vats are both an event loop and
;;; | | | a container for storing actor state. Surprise! The
;;; | | | vat is actually wrapping the container, which is called
;;; | | | an "actormap". While vats do not expose their actormaps,
;;; | | | Goblins has made a novel change by allowing actormaps to
;;; | | | be used as independent first-class objects. Most users
;;; | | | will rarely do this, but first-class usage of actormaps
;;; | | | is still useful if integrating Goblins with an existing
;;; | | | event loop (such as one for a video game or a GUI) or for
;;; | | | writing unit tests.
;;; | | |
;;; | | | The keys to actormaps are references (called "refrs")
;;; | | | and the values are current behavior. This is described
;;; | | | below.
;;; | | |
;;; | | | Actormaps also technically operate on "turns", which are
;;; | | | a transactional operation. Once a turn begins, a dynamic
;;; | | | "syscaller" (or "actor context") is initialized so that
;;; | | | actors can make changes within this transaction. At the
;;; | | | end of the turn, the user of actormap-turn is presented
;;; | | | with the transactional actormap (called "transactormap")
;;; | | | which can either be committed or not to the current mutable
;;; | | | actormap state ("whactormap", which stands for
;;; | | | "weak hash actormap"), alongside a queue of messages that
;;; | | | were scheduled to be run from actors in this turn using <-,
;;; | | | and the result of the computation run.
;;; | | |
;;; | | | However, few users will operate using actormap-turn directly,
;;; | | | and will instead either use actormap-poke! (which automatically
;;; | | | commits the transaction if it succeeds or propagates the error)
;;; | | | or actormap-peek (which returns the result but throws away the
;;; | | | transaction; useful for getting a sense of what's going on
;;; | | | without committing any changes to actor state).
;;; | | | Or, even more commonly, they'll just use a vat and never think
;;; | | | about actormaps at all.
;;; | | |
;;; | | | .--- A reference to an object or actor.
;;; | | | | Traditionally called a "ref" by the ocap community, but
;;; | | | | scheme already uses "-ref" everywhere so we call it
;;; | | | | "refr" instead. Whatever.
;;; | | | |
;;; | | | | Anyway, these are the real "capabilities" of Goblins'
;;; | | | | "object capability system". Holding onto one gives you
;;; | | | | authority to make invocations with <- or $, and can be
;;; | | | | passed around to procedure or actor invocations.
;;; | | | | Effectively the "moral equivalent" of a procedure
;;; | | | | reference. If you have it, you can use (and share) it;
;;; | | | | if not, you can't.
;;; | | | |
;;; | | | | Actually, technically these are local-live-refrs...
;;; | | | | see "The World of Refrs" below for the rest of them.
;;; | | | |
;;; | | | | .--- We're now at the "object behavior" side of
;;; | | | | | things. I wish I could avoid talking about
;;; | | | | | "mactors" but we're talking about the actual
;;; | | | | | implementation here so... "mactor" stands for
;;; | | | | | "meta-actor", and really there are a few
;;; | | | | | "core kinds of behavior" (mainly for promises
;;; | | | | | vs object behavior). But in the general case,
;;; | | | | | most objects from a user's perspective are the
;;; | | | | | mactor:object kind, which is just a wrapper
;;; | | | | | around the current object handler (as well as
;;; | | | | | some information to track when this object is
;;; | | | | | "becoming" another kind of object.
;;; | | | | |
;;; | | | | | .--- Finally, "object"... a term that is
;;; | | | | | | unambiguous and well-understood! Well,
;;; | | | | | | "object" in our system means "references
;;; | | | | | | mapping to an encapsulation of state".
;;; | | | | | | Refrs are the reference part, so
;;; | | | | | | object-handlers are the "current state"
;;; | | | | | | part. The time when an object transitions
;;; | | | | | | from "one" behavior to another is when it
;;; | | | | | | returns a new handler wrapped in a "become"
;;; | | | | | | wrapper specific to this object (and
;;; | | | | | provided to the object at construction
;;; | | | | | | time)
;;; | | | | | |
;;; V V V V V V
;;; (nod e (vat (actormap {refr: (mactor object-handler)})))
;;;
;;;
;;; Whew! That's a lot of info, so go take a break and then we'll go onto
@ -376,7 +376,7 @@
;;; '----------------'----------------' :
;;;
;;; On the left hand side we see live references (only valid within this
;;; process runtime or between machi nes across captp sessions) and
;;; process runtime or between nod es across captp sessions) and
;;; offline-storeable references (sturdy refrs, a kind of bearer URI,
;;; and certificate chains, which are like "deeds" indicating that the
;;; possessor of some cryptographic material is permitted access).
@ -386,8 +386,8 @@
;;; capability, as well as authority to produce these offline-storeable
;;; objects).
;;;
;;; Live references subdivide into local (on the same machi ne) and
;;; remote (on a foreign machi ne). These are typed as either
;;; Live references subdivide into local (on the same nod e) and
;;; remote (on a foreign nod e). These are typed as either
;;; representing an object or a promise.
;;;
;;; (Local references also further subdivide into "near" and "far",
@ -427,8 +427,8 @@
( _make-local-promise-refr vat-connector ) )
;; Captp-connector should be a procedure which both sends a message
;; to the local machi ne representative actor, but also has something
;; serialized that knows which specific remote machi ne + session this
;; to the local nod e representative actor, but also has something
;; serialized that knows which specific remote nod e + session this
;; corresponds to (to look up the right captp session and forward)
( struct remote-refr live-refr ( captp-connector sealed-pos ) )
@ -538,7 +538,7 @@
;;; it is sure to correspond to a mactor:object. A local-promise-refr can
;;; correspond to any object state *except* for mactor:object (if a promise
;;; resolves to a local object, it must point to it via mactor:local-link.)
;;; (remote-refrs of course never correspond to a mactor on this machi ne;
;;; (remote-refrs of course never correspond to a mactor on this nod e;
;;; those are managed by captp.)
;;;
;;; See also:
@ -610,7 +610,7 @@
( struct mactor:remote-link mactor:eventual
( point-to ) )
;; Link to an object on the same machi ne.
;; Link to an object on the same nod e.
( struct mactor:local-link mactor
( point-to ) )
@ -1325,7 +1325,7 @@
` # ( success , ( void ) ) ] ) ]
;; But if it's a remote promise then we queue it in the waiting
;; messages because we prefer to have messages "swim as close
;; as possible to the machi ne barrier where possible", with
;; as possible to the nod e barrier where possible", with
;; the exception of questions/answers which always cross over
;; (see mactor:question handling later in this procedure)
[ ( ? remote-promise-refr? )