Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

document Promise temporality and VowTools #10141

Merged
merged 2 commits into from
Sep 26, 2024
Merged

document Promise temporality and VowTools #10141

merged 2 commits into from
Sep 26, 2024

Conversation

turadg
Copy link
Member

@turadg turadg commented Sep 24, 2024

incidental

Description

Document VowTools and also the kinds of Promises that one has to keep in mind when working with durable promises (vows).

Security Considerations

none

Scaling Considerations

none

Documentation Considerations

We might point to this reference material from docs.agoric.com

Testing Considerations

n/a

Upgrade Considerations

n/a

Copy link

cloudflare-workers-and-pages bot commented Sep 24, 2024

Deploying agoric-sdk with  Cloudflare Pages  Cloudflare Pages

Latest commit: 392795f
Status: ✅  Deploy successful!
Preview URL: https://811bbe09.agoric-sdk.pages.dev
Branch Preview URL: https://ta-await-when.agoric-sdk.pages.dev

View logs

*/

/**
* @typedef VowTools
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The formatting here looks kinda dense, so I looked for a typedoc rendering at https://ta-await-when.agoric-sdk.pages.dev/modules/_agoric_vow but I don't see one. hm.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll clean this up in a future PR that moves them into a .ts

When working with SwingSet, it's crucial to understand how asynchronous operations interact with the system's execution model. A **vat** (a unit of isolated execution in SwingSet) may restart or terminate before an asynchronous operation completes. Although JavaScript's `await` keyword allows you to write asynchronous code that resembles synchronous code, you must be mindful of events that could prevent a promise from settling:

- **Underlying condition never satisfied**: The condition required for the promise to resolve may never occur.
- **Vat restarts or upgrades before settlement**: The promise may be severed if the vat restarts or upgrades before it settles.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"the vat" is sort of ambiguous - there are typically 2 vats in question: the vat that exports a promise and the one that subscribes to it.

In some cases there's just 1 vat - promises that aren't exported. But those are sort of uninteresting here.

It's also possible to have more than 1 subscriber, so in general, there are N>=1 vats involved.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I agree there are in general 2 (or more) parties involved in a promise, and either can upgrade, I believe this document is squarely on the side of the "decider" of the promise. Aka I don't believe we care much about handling disconnected promises here. Maybe we can make that more clear.

Copy link
Member

@dckc dckc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very useful stuff to have documented!

packages/SwingSet/docs/async.md Outdated Show resolved Hide resolved
packages/SwingSet/docs/async.md Outdated Show resolved Hide resolved
Copy link
Member

@gibson042 gibson042 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the promise classifications.

packages/SwingSet/docs/async.md Outdated Show resolved Hide resolved
packages/SwingSet/docs/async.md Outdated Show resolved Hide resolved
packages/SwingSet/docs/async.md Outdated Show resolved Hide resolved
packages/SwingSet/docs/async.md Outdated Show resolved Hide resolved
Copy link
Member

@mhofman mhofman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is a SwingSet doc, it's a little tricky to explain "Prompt" as it assumes some behavior of the host (cosmic-swingset in our case) to not inject I/O before quiescence, and for the APIs triggering vat upgrades to be directly driven by I/O without previous involvement of the vat getting upgraded (a fun example of that would be upgrading the bootstrap vat through core-eval, as it's the bootstrap vat that processes core eval messages)

packages/SwingSet/docs/async.md Outdated Show resolved Hide resolved
When working with SwingSet, it's crucial to understand how asynchronous operations interact with the system's execution model. A **vat** (a unit of isolated execution in SwingSet) may restart or terminate before an asynchronous operation completes. Although JavaScript's `await` keyword allows you to write asynchronous code that resembles synchronous code, you must be mindful of events that could prevent a promise from settling:

- **Underlying condition never satisfied**: The condition required for the promise to resolve may never occur.
- **Vat restarts or upgrades before settlement**: The promise may be severed if the vat restarts or upgrades before it settles.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I agree there are in general 2 (or more) parties involved in a promise, and either can upgrade, I believe this document is squarely on the side of the "decider" of the promise. Aka I don't believe we care much about handling disconnected promises here. Maybe we can make that more clear.

packages/SwingSet/docs/async.md Outdated Show resolved Hide resolved
packages/SwingSet/docs/async.md Outdated Show resolved Hide resolved
packages/SwingSet/docs/async.md Outdated Show resolved Hide resolved
packages/SwingSet/docs/async.md Outdated Show resolved Hide resolved
packages/SwingSet/docs/async.md Outdated Show resolved Hide resolved
packages/SwingSet/docs/async.md Outdated Show resolved Hide resolved
packages/SwingSet/docs/async.md Outdated Show resolved Hide resolved
packages/SwingSet/docs/async.md Outdated Show resolved Hide resolved
@turadg turadg marked this pull request as ready for review September 25, 2024 21:18
Copy link
Member

@mhofman mhofman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going over the prompt promise details again, I realized we could better explain the interactions between the host and swingset. Sorry for the churn.

@@ -34,6 +64,7 @@ export const prepareBasicVowTools = (zone, powers = {}) => {
const watchUtils = makeWatchUtils();
const asVow = makeAsVow(makeVowKit);

// DONOTMERGE this needs an issue!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder to yourself :)

packages/SwingSet/docs/async.md Outdated Show resolved Hide resolved
packages/SwingSet/docs/async.md Outdated Show resolved Hide resolved
@turadg
Copy link
Member Author

turadg commented Sep 26, 2024

I force pushed to cleanup commits, thinking this had been approved. Requesting another round of review…

@turadg turadg requested a review from mhofman September 26, 2024 16:04
Copy link
Member

@michaelfig michaelfig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Only adopt my suggestions if you really want to... this nitpicking likely has diminishing returns. 😉


When working with SwingSet, it's crucial to understand how asynchronous operations interact with the system's execution model. A **vat** (a unit of isolated execution in SwingSet) may restart or terminate before an asynchronous operation completes. Although JavaScript's `await` keyword allows you to write asynchronous code that resembles synchronous code, you must be mindful of events that could prevent a promise from settling:

- **Underlying condition never satisfied**: The condition required for the promise to resolve may never occur.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- **Underlying condition never satisfied**: The condition required for the promise to resolve may never occur.
- **Underlying condition never satisfied**: The condition required for the promise to settle may never occur.

- **Prompt Promises**:
- **Settlement**: Before any new I/O occurs, possibly over multiple cranks.
- **Dependencies**: No external input required, but may involve inter-vat asynchronous operations.
- **Example**: Internal message passing between vats that resolves before any new external events.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- **Example**: Internal message passing between vats that resolves before any new external events.
- **Example**: Internal message passing between vats that settles before any new external events.


Understanding the temporality of promises in SwingSet helps you write robust asynchronous code that behaves predictably, even in the face of vat restarts, upgrades, or terminations. By being aware of the differences between Immediate, Prompt, and Delayed promises, you can design your smart contracts and applications to be more resilient and efficient.

- **Immediate Promises** are resolved within the same crank and are safe from vat restarts or upgrades during that crank.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- **Immediate Promises** are resolved within the same crank and are safe from vat restarts or upgrades during that crank.
- **Immediate Promises** are settled within the same crank and are safe from vat restarts or upgrades during that crank.


## Immediate Promises

An **Immediate** promise is one that settles within the same Crank as its creation (see [Kernel Cycles](./state.md)). We refer to this as "Immediate" because it occurs before any further message deliveries into the vat, similar to how promise reaction callbacks happen before `setImmediate` callbacks in JavaScript.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
An **Immediate** promise is one that settles within the same Crank as its creation (see [Kernel Cycles](./state.md)). We refer to this as "Immediate" because it occurs before any further message deliveries into the vat, similar to how promise reaction callbacks happen before `setImmediate` callbacks in JavaScript.
An **Immediate** promise is one that settles within the same Crank as its creation (see [Kernel Cycles](./state.md)). We refer to this as "Immediate" because it occurs before any further message deliveries into the vat, similar to how all promise reaction callbacks happen before any JavaScript event callbacks (such as those queued by `setImmediate`).

Copy link
Member

@mhofman mhofman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I would consider the clarification around resolve/settle worthwhile.

Co-authored-by: Richard Gibson <richard.gibson@gmail.com>
Co-authored-by: Mathieu Hofman <86499+mhofman@users.noreply.github.com>
Co-authored-by: Michael FIG <mfig@agoric.com>
@turadg turadg added automerge:rebase Automatically rebase updates, then merge bypass:integration Prevent integration tests from running on PR labels Sep 26, 2024
@mergify mergify bot merged commit 0b1501a into master Sep 26, 2024
92 of 97 checks passed
@mergify mergify bot deleted the ta/await-when branch September 26, 2024 22:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge:rebase Automatically rebase updates, then merge bypass:integration Prevent integration tests from running on PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants