Skip to content

Commit fc68284

Browse files
committed
better docs
1 parent 68cfb17 commit fc68284

File tree

1 file changed

+75
-2
lines changed
  • docs/metatype.dev/docs/reference/runtimes/substantial

1 file changed

+75
-2
lines changed

docs/metatype.dev/docs/reference/runtimes/substantial/index.mdx

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,86 @@ Additionally, if we were to shut down the Typegate node executing it and then re
3737

3838
## Key Concepts
3939

40+
41+
### Backend
42+
43+
This abstraction implements a set of atomic operations that allows Typegate to persist and recover the workflow state. Currently, we have the **Redis** backend available, along with others like **fs** and **memory**, which are primarily intended for development or testing purposes.
44+
4045
### Workflows
4146

4247
A special type of function with **durable state** and an execution mechanism directly tied to time. A workflow can also trigger other workflows (child workflows).
4348

44-
### Backend
49+
#### Persistence and Lifecycle
4550

46-
This abstraction implements a set of atomic operations that allows Typegate to persist and recover the workflow state. Currently, we have the **Redis** backend available, along with others like **fs** and **memory**, which are primarily intended for development or testing purposes.
51+
* **Context**
52+
53+
The context object contains the workflow input (namely `kwargs` as seen in the example above), but it can also be thought as a namespace that contains all of the core functions used for durableness.
54+
55+
* **Interrupts**
56+
57+
An special state of the program that is produced by any function that can trigger a workflow **replay**.
58+
59+
One simple example of such function is when you want to wait for a given amount of time, Substantial will save the current time and the end time, interrupts the workflow then requeue it to execute later.
60+
Any agent (Typegate node) that picks the workflow, will **replay** it, the cycle repeats until the actual current time is greater or equal to the end time.
61+
62+
```typescript
63+
await ctx.sleep(24 * 3600 * 1000); // 1 day
64+
```
65+
66+
* **Save**
67+
68+
A save is one of the main building blocks of a workflow, many functions avalaiable on the context object relays on it.
69+
70+
This is mainly because, a save call converts any function into a durable one: the function output is saved.
71+
This ensures that when a workflow is resumed(after a typgate reboot for example) or replayed (after interrupts), if the the result was saved the saved function result will be
72+
73+
```typescript
74+
// For example, if the ouptut was 7, after replay, save will not execute the function inside but directly return the
75+
const rand = await ctx.save(() => Math.random());
76+
77+
// If you keep in mind that the workflow can be replayed many times
78+
// A save call should make more sense!
79+
const now = await ctx.save(() => Date.now());
80+
81+
// And even more for functions that can produce outside effects
82+
const result = await ctx.save(sendEmail());
83+
```
84+
85+
:::info Notes
86+
87+
Only json-compliant values can be persisted.
88+
89+
:::
90+
91+
92+
* **Send/Receive**
93+
94+
You can send events to a workflow through GraphQL, any receive call on the workflow will await for it and will **interrupt** the workflow if it was not noticed yet.
95+
```gralhql
96+
query {
97+
awesomeSend(
98+
run_id: "<workflow_run_id>",
99+
event: { name: "myEvent", payload: 1234 }
100+
)
101+
}
102+
```
103+
104+
```typescript
105+
const value = await ctx.receive<number>("myEvent"); // 1234
106+
```
107+
108+
* **ensure**
109+
110+
It's a function that takes a function that returns a boolean, if the returned value is false, it will **interrupt** the workflow.
111+
112+
```typescript
113+
const secret = await ctx.receive<string>("secret");
114+
await ctx.ensure(() => secret == "top_secret");
115+
```
116+
117+
#### Filters
118+
119+
TODO
47120

48121
### Run
49122

0 commit comments

Comments
 (0)