9. Vanes
In this lesson we're going to look at interacting with vanes (kernel modules). The API for each vane consists of tasks it can take, and gifts it can return. The tasks and gifts 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 tasks and gifts 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 gifts the vane sends back in response will arrive in the +on-arvo
arm of your agent. The +on-arvo
arm exclusively handles such vane gifts. The gifts 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 tasks 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 gifts 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, gifts 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 tasks it takes and gifts it produces.
Each vane's tasks and gifts are defined in
lull.hoon
Each vane's section of the Arvo documentation includes an API reference that explains its tasks and gifts, as well as an Examples section demonstrating their usage.
Vane tasks can be sent to vanes by
%pass
ing them an%arvo
$card
.Vane gifts 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