|
|
|
|
@ -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 "machine/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 Machine 1 has to |
|
|
|
|
;;; objects in Machine 2 (at the top) and references Machine 2 has to |
|
|
|
|
;;; Machine 1. Both machines in this diagram are cooperating to preserve |
|
|
|
|
;;; - Zooming out the farthest is the "node/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 Node 1 has to |
|
|
|
|
;;; objects in Node 2 (at the top) and references Node 2 has to |
|
|
|
|
;;; Node 1. Both nodes 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 |
|
|
|
|
;;; machine's perspective that this is the case... generally it's in |
|
|
|
|
;;; node'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 ocap community, inspired by the kinds of diagrams in Mark |
|
|
|
|
;;; in the OCap 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: |
|
|
|
|
;;; |
|
|
|
|
;;; (machine (vat (actormap {refr: (mactor object-handler)}))) |
|
|
|
|
;;; (node (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 machine in Goblins is basically an OS process. |
|
|
|
|
;;; .--- A node in Goblins is basically an OS process. |
|
|
|
|
;;; | However, the broader Goblins CapTP/MachineTP network is |
|
|
|
|
;;; | made up of many machines. A connection to another machine |
|
|
|
|
;;; | is the closest amount of "assurance" a Goblins machine has |
|
|
|
|
;;; | made up of many nodes. A connection to another node |
|
|
|
|
;;; | is the closest amount of "assurance" a Goblins node has |
|
|
|
|
;;; | that it is delivering to a specific destination. |
|
|
|
|
;;; | Nonetheless, Goblins users generally operate at the object |
|
|
|
|
;;; | reference level of abstraction, even across machines. |
|
|
|
|
;;; | reference level of abstraction, even across nodes. |
|
|
|
|
;;; | |
|
|
|
|
;;; | An object reference on the same machine is considered |
|
|
|
|
;;; | "local" and an object reference on another machine is |
|
|
|
|
;;; | An object reference on the same node is considered |
|
|
|
|
;;; | "local" and an object reference on another node 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 |
|
|
|
|
;;; (machine (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 |
|
|
|
|
;;; (node (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 machines across captp sessions) and |
|
|
|
|
;;; process runtime or between nodes 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 machine) and |
|
|
|
|
;;; remote (on a foreign machine). These are typed as either |
|
|
|
|
;;; Live references subdivide into local (on the same node) and |
|
|
|
|
;;; remote (on a foreign node). 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 machine representative actor, but also has something |
|
|
|
|
;; serialized that knows which specific remote machine + session this |
|
|
|
|
;; to the local node representative actor, but also has something |
|
|
|
|
;; serialized that knows which specific remote node + 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 machine; |
|
|
|
|
;;; (remote-refrs of course never correspond to a mactor on this node; |
|
|
|
|
;;; 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 machine. |
|
|
|
|
;; Link to an object on the same node. |
|
|
|
|
(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 machine barrier where possible", with |
|
|
|
|
;; as possible to the node barrier where possible", with |
|
|
|
|
;; the exception of questions/answers which always cross over |
|
|
|
|
;; (see mactor:question handling later in this procedure) |
|
|
|
|
[(? remote-promise-refr?) |
|
|
|
|
|