9. Vanes
In this lesson we're going to look at interacting with vanes (kernel modules). The API for each vane consists of $task
s it can take, and $gift
s it can return. The $task
s and $gift
s for each vane are defined in its section of /sys/lull.hoon
. Here's the $task:iris
s and $gift:iris
s for Iris, the HTTP client vane, as an example:
|%
+$ gift
$% [%request id=@ud request=request:http]
[%cancel-request id=@ud]
[%http-response =client-response]
==
+$ task
$~ [%vega ~]
$% $>(%born vane-task)
$>(%trim vane-task)
$>(%vega vane-task)
[%request =request:http =outbound-config]
[%cancel-request ~]
[%receive id=@ud =http-event:http]
==
The API of each vane is documented in its respective section of the Arvo documentation. Each vane has a detailed API reference and examples of their usage. There are far too many $task
s and $gift
s across the vanes to cover here, so in the Example
section of this document, we'll just look at a single, simple example with a Behn timer. The basic pattern in the example is broadly applicable to the other vanes as well.
Sending a vane task
A $task
can be sent to a vane by %pass
ing it an %arvo
card. We touched on these in the Cards lesson, but we'll briefly recap it here. The type of the card is as follows:
[%pass path %arvo note-arvo]
The $path
will just be the $wire
you want the response to arrive on. The $note-arvo
is the following union:
+$ note-arvo
$~ [%b %wake ~]
$% [%a task:ames]
[%b task:behn]
[%c task:clay]
[%d task:dill]
[%e task:eyre]
[%g task:gall]
[%i task:iris]
[%j task:jael]
[%k task:khan]
[%l task:lick]
[%$ %whiz ~]
[@tas %meta vase]
==
The letter tags just specify which vane it goes to, and then follows the $task
itself. Here are a couple of examples. The first sends a %wait
$task:behn
to Behn, setting a timer to go off one minute in the future. The second sends a %warp
$task:clay
to Clay, asking whether sys.kelvin
exists on the %base
desk.
[%pass /some/wire %arvo %b %wait (add ~m1 now.bowl)]
[%pass /some/wire %arvo %c %warp our.bowl %base ~ %sing %u da+now.bowl /sys/kelvin]
Receiving a vane gift
Once a $task
has been sent to a vane, any $gift
s the vane sends back in response will arrive in the +on-arvo
arm of your agent. The +on-arvo
arm exclusively handles such vane $gift
s. The $gift
s will arrive in a $sign-arvo
, along with the $wire
specified in the original request. The +on-arvo
arm produces a (quip card _this)
like usual, so it would look like:
++ on-arvo
|= [=wire =sign-arvo]
^- (quip card _this)
.....
A $sign-arvo
is the following structure, defined in lull.hoon
:
+$ sign-arvo
$% [%ames gift:ames]
$: %behn
$% gift:behn
$>(%wris gift:clay)
$>(%writ gift:clay)
$>(%mere gift:clay)
$>(%unto gift:gall)
==
==
[%clay gift:clay]
[%dill gift:dill]
[%eyre gift:eyre]
[%gall gift:gall]
[%iris gift:iris]
[%jael gift:jael]
[%khan gift:khan]
[%lick gift:lick]
==
The head of the $sign-arvo
will be the name of the vane like %behn
, %clay
, etc. The tail will be the $gift
itself. Here are a couple of $sign-arvo
examples, and the responses to the example $task
s in the previous section:
[%behn %wake ~]
[ %clay
[ %writ
p
[ ~
[ p=[p=%u q=[%da p=~2021.11.17..13.55.00..c195] r=%base]
q=/sys/kelvin
r=[p=%flag q=[#t/?(%.y %.n) q=0]]
]
]
]
]
The typical pattern is to first test the $wire
with something like a wutlus (?+
) expression, and then test the $sign-arvo
. Since most $gift
s are head-tagged, you can test both the vane and the gift at the same time like:
?+ sign-arvo (on-arvo:def wire sign-arvo)
[%behn %wake *]
.....
....
Example
Here's a very simple example that takes a poke of a @dr
(a relative date-time value) and sends Behn a %wait
$task:behn
, setting a timer to go off @dr
in the future. When the timer goes off, +on-arvo
will take the %wake
$gift:behn
and print "Ding!" to the terminal.
Let's examine the +on-poke
arm:
++ on-poke
|= [=mark =vase]
^- (quip card _this)
?+ mark (on-poke:def mark vase)
%noun
:_ this
:~ [%pass /timers %arvo %b %wait (add now.bowl !<(@dr vase))]
==
==
A Behn %wait
task has the format [%wait @da]
- the @da
(an absolute date-time value) is the time the timer should go off. The $vase
of the poke takes a @dr
, so we extract it directly into an +add
expression, producing a date-time @dr
from now. Behn will receive the %wait
task and set the timer in Unix. When it fires, Behn will produce a %wake
$gift:behn
and deliver it to +on-arvo
, on the $wire
we specified (/timers
). Here's the +on-arvo
arm:
++ on-arvo
|= [=wire =sign-arvo]
^- (quip card _this)
?+ wire (on-arvo:def wire sign-arvo)
[%timers ~]
?+ sign-arvo (on-arvo:def wire sign-arvo)
[%behn %wake *]
?~ error.sign-arvo
((slog 'Ding!' ~) `this)
(on-arvo:def wire sign-arvo)
==
==
We remark that, just like in the case of agent-agent communication, $gift
s from Arvo are also routed $wire
before $sign-arvo
.
First we check the $wire
is /timers
, and then we check the $sign-arvo
begins with [%behn %wake ....]
. Behn's %wake
gift has the following format:
[%wake error=(unit tang)]
The .error
is null if the timer fired successfully, and contains an error in the $tang
if it did not. We therefore test whether .error.sign-arvo
is ~
, and if it is, we print Ding!
to the terminal. If the $wire
, $sign-arvo
or .error
are something unexpected, we pass it to %default-agent
, which will just crash and print an error message.
Let's try it out. Save the agent above as /app/ding.hoon
on the %base
desk and |commit %base
. Then, start the agent with |rein %base [& %ding]
.
Next, in the Dojo let's try poking our agent, setting a timer for five seconds from now:
> :ding ~s5
>=
After approximately five seconds, we see the timer fired successfully:
> Ding!
Summary
Each vane has an API composed of
$task
s it takes and$gift
s it produces.Each vane's
$task
s and$gift
s are defined inlull.hoon
Each vane's section of the Arvo documentation includes an API reference that explains its
$task
s and$gift
s, as well as an Examples section demonstrating their usage.Vane
$task
s can be sent to vanes by%pass
ing them an%arvo
$card
.Vane
$gift
s come back to the+on-arvo
arm of the agent core in a$sign-arvo
.
Exercises
Run through the Example yourself if you've not done so already.
Have a look at some vane sections of
lull.hoon
to familiarize yourself with its structure.Have a quick look at the API reference sections of a couple of vanes in the Arvo documentation.
Last updated