-
Notifications
You must be signed in to change notification settings - Fork 207
Exo and Zone API Patterns
0xPatrick edited this page Nov 26, 2024
·
2 revisions
This guide provides an overview of key components in the exo API. Please note that this guide may contain simplifications, and you should refer to the official documentation for complete information.
- KV store, similar to native
Map
- Can live on its own or referenced by other exos in the same lexical scope
- unique value store, similar to native
Set
- Can live on its own or referenced by other exos in the same lexical scope
- Creates an exo object with methods
- The exo object itself is Passable, not its individual methods
- Methods can lexically capture ("close over") stateful data from their scope
- The preferred way to write a Far function in agoric-sdk.
Far
is how we mark an object to be exposed for remote interaction.
- Has an explicit
state
record - Returns a function (typically named
makeFoo
) that creates instances of the class - Initialization:
- Takes an initialization function with construction parameters
- This function returns a record used to create the instance's
state
record - The
makeFoo
function's parameters match the initialization function's parameters
- Similar to
zone.exoClass()
- Kits are multi-faceted (i.e.,
Record<string, Record<string, Fn>>
instead of justRecord<string, Fn>
) - Often, an attenuated version is returned (e.g.,
kit.holder
) - Used when two or more exos need to share state, functionality needs to be attenuated, or the instance relies on a handler that must implement a certain interface.
Determined by the zone passed to it - typically heap zone or durable zone bound to baggage.
All exo state needs to be Passable
- Calls to
zone.exo()
,zone.exoClass()
andzone.exoClassKit()
are typically wrapped in prepare functions which need to return synchronously.zone.exo()
creates an instance directly, where zone.exoClass() and zone.exoClassKit() returnmake*()
functions for creating an instance of the class. - The prepare statements need to return synchronously to satisfy the "prepare in first crank*" constraint - all exos need to be defined before the object receives any incoming message calls from other vats.
- *"crank" refers to a unit of execution in the SwingSet VM's event loop. It is everything that happens from an empty stack and promise queue to the next empty stack and promise queue. A turn is everything that happens between an empty stack and the next empty stack, for a given vat.
- In a previous version of this post, "synchronous prelude" was conflated with "prepare in first crank". Synchronous prelude refers to code that's called before the first
await
in a function, and is used to explainawait
safety rules. -
await null
is used in the top-level of functions that rely on synchronous calls before the firstawait
, to ensure an empty stack. Without this, there is no guarantee that the synchronous calls happen promptly.
Originally posted in discussions: https://github.com/Agoric/agoric-sdk/discussions/9651