on master help sign in
update behn docs

- update overview - update api ref - add scry ref - add examples

commit2f400d5c0a904789d08ae3122dccae666aa0dea0 authortinnus-napbus <admin@tinnus-napbus.xyz> dateMon 16 Aug 2021, 18:15 (5 years ago) parentc6ab0de
6 files changed+321−259
content/docs/arvo/behn/_index.md+16 content/docs/arvo/behn/behn-api.md−246 content/docs/arvo/behn/behn.md+9−13 content/docs/arvo/behn/examples.md+95 content/docs/arvo/behn/scry.md+46 content/docs/arvo/behn/tasks.md+155
content/docs/arvo/behn/_index.md+16
@@ -5,3 +5,19 @@ sort_by = "weight"
55template = "sections/docs/chapters.html"
66insert_anchor_links = "right"
77+++
8+
9+## [Overview](/docs/arvo/behn/behn)
10+
11+An overview of Behn, Urbit's timer vane.
12+
13+## [API Reference](/docs/arvo/behn/tasks)
14+
15+The `task`s Behn takes and the `gift`s it returns.
16+
17+## [Scry Reference](/docs/arvo/behn/scry)
18+
19+The scry endpoints of Behn.
20+
21+## [Examples](/docs/arvo/behn/examples)
22+
23+Practical examples of using Behn's `task`s.
content/docs/arvo/behn/behn-api.mddeleted−246
@@ -1,246 +0,0 @@
1−+++
2−title = "API Reference"
3−weight = 10
4−template = "doc.html"
5−+++
6−
7−In this document we describe the public interface for Behn. Namely, we describe
8−each `task` that Behn can be `pass`ed, and which `gift`(s) Behn can `give` in return.
9−
10−
11−## Tasks
12−
13−### `%born`
14−
15−Each time you start your Urbit, the Arvo kernel calls the `%born` task for Behn. When
16−called, Behn gets the current time from Unix and updates its list of timers
17−accordingly.
18−
19−#### Accepts
20−
21−```hoon
22−[~]
23−```
24−
25−#### Returns
26−
27−`%born` does not return a `gift`.
28−
29−
30−### `%crud`
31−
32−`%crud` is called whenever an error involving Behn occurs, such as trying to
33−`%wake` a program that has crashed.
34−
35−When called, it checks to see if the set of timers is empty. If so, it prints
36−an error report containing `error`, otherwise it passes the error to `+wake`.
37−
38−#### Accepts
39−
40−```hoon
41−[tag=@tas error=tang]
42−```
43−Here, `tag` is a `@tas` denoting the type of error, and `error` is an error message.
44−
45−#### Returns
46−
47−```hoon
48−[%wake %behn-crud-no-timer tag error]
49−```
50−
51−If the set of timers is nonempty when Behn is `%pass`ed a `%crud` `task`, Behn
52−`%give`s a `%wake` `card` containing the error to the next client in the set of timers.
53−
54−
55−#### Example
56−
57−The most common error that occurs is when Behn tries to `%wake` up a program that has crashed. When this happens
58−the entire event (i.e. sequence of `move`s) that led up to the `%wake` is thrown
59−away, and Vere then causes the kernel to `pass` Behn a `%crud` `task` containing
60−the stack trace.
61−
62−
63−### `%drip`
64−
65−`%drip` allows one to delay a `gift` until a timer set for `now` fires.
66−
67−A Client `%slip`s Behn a `%drip` task wrapping a `gift` to be `give`n to a Target.
68−This launches a sequence of `move`s as written here:
69−
70−```
71−Client -- %slip %drip --> Behn -- %pass %wait --> Behn -- %give %wake --> Behn -- %give %meta --> Target
72−```
73−Here the `%meta` `move` is a wrapper for the `%gift` inside of the initial `%drip` wrapper.
74−
75−`%drip` only handles `gift`s, and can only schedule `gift`s for as soon as
76−possible after the prescribed timer fires.
77−
78−
79−#### Accepts
80−
81−```hoon
82−mov=vase
83−```
84−
85−`%drip` takes in a `%give` `move` in a `vase`.
86−
87−#### Returns
88−
89−In response to a `%drip` `task`, Behn will `%pass` a `%wait` to itself, which
90−then triggers a `%wake` `gift` to itself, which then causes Behn to `%give` a `%meta` `gift` containing
91−the `gift` originally `%give`n to Behn when `%drip` was first called. That makes
92−Behn its own client for `%drip`.
93−
94−#### Example
95−
96−
97−Say an app (the Target) is subscribed to updates from Clay (the Client). If Clay `%give`s
98−updates to the app directly and the app crashes, this may cause Clay to crash as
99−well. If instead Clay `%pass`es Behn a `%drip` `task` wrapping the update
100−`gift`, Behn will set a timer for `now` that, when fired, will cause the update
101−`gift` to be given. If it causes a crash then it will have been in response to
102−the `%drip` move, thereby isolating Clay from the crash. Thus `%drip` acts as a sort of buffer against cascading
103−sequences of crashes.
104−
105−
106−
107−### `%huck`
108−
109−Immediately gives back an input move.
110−
111−#### Accepts
112−
113−```hoon
114−mov=vase
115−```
116−
117−Behn takes in a `move` contained in a `vase`.
118−
119−#### Returns
120−
121−```hoon
122−[%give %meta mov]
123−```
124−
125−Behn returns the input `move` as a `%meta` `gift`.
126−
127−
128−
129−### `%rest`
130−
131−Cancels a timer that was previously set.
132−
133−Behn takes in a `@da` and cancels the timer at that time if it exists, then
134−adjusts the next wakeup call from Unix if necessary.
135−
136−#### Task
137−
138−```hoon
139−@da
140−```
141−
142−
143−#### Gift
144−
145−This `task` returns no `gift`s.
146−
147−
148−
149−### `%trim`
150−
151−This `task` is sent by the interpreter in order to free up memory.
152− This `task` is empty for Behn, since it is not a good idea to forget your timers.
153−
154−#### Accepts
155−
156−This `task` has no arguments.
157−
158−#### Returns
159−
160−This task returns nothing.
161−
162−### `%vega`
163−
164−This `task` informs the vane that the kernel has been upgraded. Behn does not do
165−anything in response to this.
166−
167−#### Accepts
168−
169−This `task` has no arguments.
170−
171−#### Returns
172−
173−This `task` returns nothing.
174−
175−
176−
177−### `%wait`
178−
179−This `task` takes in a `@da` which Behn then adds to `timers.state`, the list of timers.
180−
181−#### Accepts
182−
183−```hoon
184−@da
185−```
186−
187−#### Returns
188−
189−This `task` returns a `%wake` `gift` once the timer has fired.
190−
191−
192−### `%wake`
193−
194−This `task` is sent by the kernel when the Unix timer tells the kernel that it
195−is time for Behn to wake up. This is often caused by a `%doze` `gift` that
196−Behn originally sent to the kernel that is then forwarded to Unix, which is
197−where the real timekeeping occurs.
198−
199−Upon receiving this `task`, Behn processes the elapsed timer and then sets
200−`:next-wake`.
201−
202−`%wake` is also a `gift` that Behn can `%give`. This is done to inform other
203−vanes or apps that a timer has expired, and may include an error message.
204−
205−#### Accepts
206−
207−As a `task`, `%wake` takes in `~`.
208−
209−As a `gift`, `%wake` may include an error message.
210−
211−```hoon
212−error=(unit tang)
213−```
214−
215−
216−#### Returns
217−
218−In response to receiving this `task`, Behn may `%give` a `%doze` `gift`
219−containing the `@da` of the next timer to elapse. Behn may also `%give` a
220−`%wake` `gift` to itself.
221−
222−
223−
224−### `%wegh`
225−
226−This `task` asks Behn to product a memory usage report.
227−
228−#### Accepts
229−
230−This `task` has no arguments.
231−
232−#### Returns
233−
234−```hoon
235−:_ state :_ ~
236− :^ duct %give %mass
237− :+ %behn %|
238− :~ timers+&+timers.state
239− dot+&+state
240−```
241−
242−When Behn is `%pass`ed this `task`, it will `%give` a `%mass` `gift` in response
243−containing Behn's current memory usage.
244−
245−
246−
content/docs/arvo/behn/behn.md+9−13
@@ -3,19 +3,15 @@ title = "Overview"
33weight = 1
44template = "doc.html"
55+++
6−Our simple timer.
76
8−It allows vanes and applications to set and timer events, which are
9−managed in a simple priority queue. `%behn` produces effects to start
10−the unix timer, and when the requested `%behn` passes, unix sends wake
11−events to `%behn`, which time routes back to original sender. We don't
12−guarantee that a timer event will happen at exactly the `%behn` it was
13−set for, or even that it'll be particularly close. A timer event is a
14−request to not be woken until after the given time.
7+Urbit's timer vane.
158
16−`%eyre` uses `%behn` for timing out sessions, and `%clay` uses `%behn`
17−for keeping track of time-specified file requests. `%ames` should
18−probably use `%behn` to keep track of things like network timeouts and
19−retry timing, but it currently uses its own alarm system.
9+Behn manages timers in a simple priority queue. Other vanes and applications ask Behn to set a timer to go off at the given time, and Behn produces effects that start the timers on Unix. When the timer goes off, Unix sends an event to Behn, which then notifies the original requester. We don't gurantee that a timer event will happen at exactly the time it was set for, or even that it'll be particularly close. A timer event is a request to not be woken until after the given time.
2010
21−This article is a stub. For more information, see either `behn.hoon` or [Lesson 2.6 - Behn](/docs/hoon/hoon-school/behn) of the Hoon tutorial.
11+## Sections
12+
13+[API Reference](/docs/arvo/behn/tasks) - The `task`s Behn takes and the `gift`s it returns.
14+
15+[Scry Reference](/docs/arvo/behn/scry) - The scry endpoints of Behn.
16+
17+[Examples](/docs/arvo/behn/examples) - Practical examples of using Behn's `task`s.
content/docs/arvo/behn/examples.mdnew file+95
@@ -0,0 +1,95 @@
1++++
2+title = "Examples"
3+weight = 4
4+template = "doc.html"
5++++
6+
7+Here are a couple of practical examples of using Behn's `%wait` and `%rest` `task`s.
8+
9+## %wait
10+
11+Here we'll look at setting a timer by passing Behn a `%wait` `task` and taking the `%wake` `gift` it returns when the timer fires.
12+
13+Below is a thread which will take a `@dr` as its argument and `%pass`es Behn a `%wait` `task` to fire `@dr` in the future. When the timer fires, it'll then take the `%wake` `gift` and print it to the terminal along with the time that has elapsed.
14+
15+`wait.hoon`
16+
17+```hoon
18+/- spider
19+/+ *strandio
20+=, strand=strand:spider
21+^- thread:spider
22+|= arg=vase
23+=/ m (strand ,vase)
24+^- form:m
25+=/ delay=@dr (need !<((unit @dr) arg))
26+;< t1=@da bind:m get-time
27+=/ =task:behn [%wait (add delay t1)]
28+=/ =card:agent:gall [%pass /timer %arvo %b task]
29+;< ~ bind:m (send-raw-card card)
30+;< res=(pair wire sign-arvo) bind:m take-sign-arvo
31+?> ?=([%timer ~] p.res)
32+?> ?=([%behn %wake *] q.res)
33+%- (slog ~[leaf+"Gift: {<+.q.res>}"])
34+?~ error.q.res
35+ ;< t2=@da bind:m get-time
36+ %- (slog ~[leaf+"Time elapsed: {<`@dr`(sub t2 t1)>}"])
37+ (pure:m !>(~))
38+%- (slog u.error.q.res)
39+(pure:m !>(~))
40+```
41+
42+Save the thread to `/ted/wait.hoon` and `|commit %home`. Then we can try running the thread with a `@dr` of `~s2`:
43+
44+```
45+> -wait ~s2
46+Gift: [%wake error=~]
47+Time elapsed: ~s2..0154
48+```
49+
50+As you can see, the timer has fired successfully after `~s2` and Behn has given us a `%wake` `gift`.
51+
52+## %rest
53+
54+Here we'll look at cancelling a previously set timer by passing Behn a `%rest` `task`.
55+
56+Below is a variation on the [%wake](#wake) thread. It takes a `@dr` as its argument and sets a timer that far in the future, as before. However, it also sets a second timer twice the `@dr` in the future, and then cancels the first with a `%rest` `task`. If the `%rest` `task` succeeds in cancelling the first timer, the `%wake` `gift` will arrive after double the specified delay.
57+
58+`rest.hoon`
59+
60+```hoon
61+/- spider
62+/+ *strandio
63+=, strand=strand:spider
64+^- thread:spider
65+|= arg=vase
66+=/ m (strand ,vase)
67+^- form:m
68+=/ delay=@dr (need !<((unit @dr) arg))
69+;< t1=@da bind:m get-time
70+=/ timer1=@da (add t1 delay)
71+=/ timer2=@da (add t1 (mul delay 2))
72+;< ~ bind:m (send-raw-card [%pass /timer %arvo %b %wait timer1])
73+;< ~ bind:m (send-raw-card [%pass /timer %arvo %b %wait timer2])
74+;< ~ bind:m (send-raw-card [%pass /timer %arvo %b %rest timer1])
75+;< res=(pair wire sign-arvo) bind:m take-sign-arvo
76+?> ?=([%timer ~] p.res)
77+?> ?=([%behn %wake *] q.res)
78+%- (slog ~[leaf+"Gift: {<+.q.res>}"])
79+?~ error.q.res
80+ ;< t2=@da bind:m get-time
81+ %- (slog ~[leaf+"Time elapsed: {<`@dr`(sub t2 t1)>}"])
82+ (pure:m !>(~))
83+%- (slog u.error.q.res)
84+(pure:m !>(~))
85+```
86+
87+Save the above thread to `/ted/rest.hoon`, and `|commit %home`. Let's try run it with an argument of `~s2`:
88+
89+```
90+> -rest ~s2
91+Gift: [%wake error=~]
92+Time elapsed: ~s4..00d4
93+```
94+
95+As you can see, the timer fired after four seconds, which means the two second timer was successfully cancelled by the `%rest` `task`.
content/docs/arvo/behn/scry.mdnew file+46
@@ -0,0 +1,46 @@
1++++
2+title = "Scry Reference"
3+weight = 3
4+template = "doc.html"
5++++
6+
7+Here are Behn's scry endpoints. There's only a few and they're mostly just useful for debugging. All of Behn's scries take a `%x` `care` and require the `desk` in the path prefix be empty, so the general format is `.^([type] %bx /=//=/[some-path])`.
8+
9+## /debug/timers
10+
11+A scry with a `%x` `care` and a `path` of `/debug/timers` will return the timestamp and `duct` of all timers which are currently set. The type returned is a `(list [@da duct])`.
12+
13+```
14+> .^((list [@da duct]) %bx /=//=/debug/timers)
15+~[
16+ [~2021.8.9..16.16.30..9d49 ~[/ames/pump/~wet/0 /ames]]
17+ [~2021.8.9..16.17.58..597d ~[/ames/pump/~nes/0 /ames]]
18+]
19+```
20+
21+## /timers
22+
23+A scry with a `%x` `care` and a `path` of `/timers` will return the timestamps of all timers currently set. The type returned is a `(list @da)`.
24+
25+```
26+> .^((list @da) %bx /=//=/timers)
27+~[~2021.8.9..16.17.02..9de6 ~2021.8.9..16.17.58..597d]
28+```
29+
30+## /timers/next
31+
32+A scry with a `%x` `care` and a `path` of `/timers/next` will return the timestamp of the timer set to fire next, or null if there's none. The type returned is a `(unit @da)`.
33+
34+```
35+> .^((unit @da) %bx /=//=/timers/next)
36+[~ ~2021.8.9..16.17.58..597d]
37+```
38+
39+## /timers/[da]
40+
41+A scry with a `%x` `care` and a `path` of `/timers/[da]` (where `[da]` is an absolute date) will return all timers which are scheduled to fire between now and the specified date (inclusive). The type returned is a `(list @da)`.
42+
43+```
44+> .^((list @da) %bx /=//=/timers/(scot %da (add now ~d1)))
45+~[~2021.8.9..16.17.58..597d ~2021.8.9..16.18.06..a24b]
46+```
content/docs/arvo/behn/tasks.mdnew file+155
@@ -0,0 +1,155 @@
1++++
2+title = "API Reference"
3+weight = 2
4+template = "doc.html"
5++++
6+
7+In this document we describe the public interface for Behn. Namely, we describe each `task` that Behn can be `pass`ed, and which `gift`(s) Behn can `give` in return.
8+
9+Most of Behn's `task`s are only used by the kernel or runtime. The two `task`s you're likely to use from userspace are [%wait](#wait) for setting a timer and [%rest](#rest) for cancelling a timer.
10+
11+## `%born`
12+
13+```hoon
14+[%born ~]
15+```
16+
17+Each time you start your Urbit, the Arvo kernel calls the `%born` task for Behn. When called, Behn gets the current time from Unix and updates its list of timers accordingly.
18+
19+You would not use this `task` from userspace.
20+
21+#### Returns
22+
23+Behn does not return any `gift` in response to a `%born` `task`.
24+
25+## `%rest`
26+
27+```hoon
28+[%rest p=@da]
29+```
30+
31+Cancel a timer.
32+
33+Behn takes in a `@da` and cancels the timer at that time if it exists, then adjusts the next wakeup call from Unix if necessary.
34+
35+#### Returns
36+
37+Behn does not return any `gift` in response to a `%rest` `task`.
38+
39+#### Example
40+
41+See the [%rest](/docs/arvo/behn/examples#rest) section of the Examples document.
42+
43+## `%drip`
44+
45+```hoon
46+[%drip p=vase]
47+```
48+
49+`%drip` allows one to delay a `gift` until a timer set for `now` fires.
50+
51+A Client `%slip`s Behn a `%drip` task wrapping a `gift` to be `give`n to a Target. This launches a sequence of `move`s as written here:
52+
53+```
54+Client -- %slip %drip --> Behn -- %pass %wait --> Behn -- %give %wake --> Behn -- %give %meta --> Target
55+```
56+
57+Here the `%meta` `move` is a wrapper for the `%gift` inside of the initial `%drip` wrapper.
58+
59+`%drip` only handles `gift`s, and can only schedule `gift`s for as soon as possible after the prescribed timer fires.
60+
61+`%drip` takes in a `%give` `move` in a `vase`.
62+
63+A `%drip` `task` is not likely to be used from userspace.
64+
65+#### Returns
66+
67+In response to a `%drip` `task`, Behn will `%pass` a `%wait` to itself, which then triggers a `%wake` `gift` to itself, which then causes Behn to `%give` a `%meta` `gift` containing the `gift` originally `%give`n to Behn when `%drip` was first called. That makes Behn its own client for `%drip`.
68+
69+#### Example
70+
71+Say an app (the Target) is subscribed to updates from Clay (the Client). If Clay `%give`s updates to the app directly and the app crashes, this may cause Clay to crash as well. If instead Clay `%pass`es Behn a `%drip` `task` wrapping the update `gift`, Behn will set a timer for `now` that, when fired, will cause the update `gift` to be given. If it causes a crash then it will have been in response to the `%drip` move, thereby isolating Clay from the crash. Thus `%drip` acts as a sort of buffer against cascading sequences of crashes.
72+
73+## `%huck`
74+
75+```hoon
76+[%huck syn=sign-arvo]
77+```
78+
79+Immediately gives back a `sign-arvo`.
80+
81+You would not use this `task` from userspace.
82+
83+#### Returns
84+
85+Behn returns the input `sign-arvo` as a `%heck` `gift`:
86+
87+```hoon
88+[%heck syn=sign-arvo]
89+```
90+
91+## `%trim`
92+
93+```hoon
94+[%trim p=@ud]
95+```
96+
97+This `task` is sent by the interpreter in order to free up memory. Behn does not do anything with this `task`, since it is not a good idea to forget your timers.
98+
99+You would not use this `task` from userspace.
100+
101+#### Returns
102+
103+Behn does not return any `gift` in response to a `%trim` `task`.
104+
105+## `%vega`
106+
107+```hoon
108+[%vega ~]
109+```
110+
111+This `task` informs the vane that the kernel has been upgraded. Behn does not do anything in response to this.
112+
113+You would not use this `task` from userspace.
114+
115+#### Returns
116+
117+Behn does not return any `gift` in response to a `%vega` `task`.
118+
119+## `%wait`
120+
121+```hoon
122+[%wait p=@da]
123+```
124+
125+Set timer.
126+
127+This `task` sets a timer to fire at the `@da` specified in `p`.
128+
129+#### Returns
130+
131+Behn returns a `%wake` `gift` in response to a `%wait` `task`, once the timer has fired. A `%wake` `gift` looks like:
132+
133+```hoon
134+[%wake error=(unit tang)]
135+```
136+
137+The `error` `unit` will be `~` if successful, or contain a traceback in the `tang` if the timer failed for some reason.
138+
139+#### Example
140+
141+See the [%wait](/docs/arvo/behn/tasks#wait) section of the Examples document.
142+
143+## `%wake`
144+
145+```hoon
146+[%wake ~]
147+```
148+
149+This `task` is sent by the kernel when the Unix timer tells the kernel that it is time for Behn to wake up. This is often caused by a `%doze` `gift` that Behn originally sent to the kernel that is then forwarded to Unix, which is where the real timekeeping occurs.
150+
151+You would not use this `task` from userspace.
152+
153+#### Returns
154+
155+In response to receiving this `task`, Behn may `%give` a `%doze` `gift` containing the `@da` of the next timer to elapse. Behn may also `%give` a `%wake` `gift` to itself.