As we previously discussed, most arms of an agent core produce a cell of
[effects new-agent-core], and the type we use for this is typically (quip card _this). We've covered _this, but we haven't yet looked at card effects
in detail. That's what we'll do here. In explaining cards we'll touch on some
concepts relating to the mechanics of pokes, subscriptions and other things
we've not yet covered. Don't worry if you don't understand how it all fits
together yet, we just want to give you a basic idea of cards so we can then
dig into how they work in practice.
card type
The card:agent:gall type (henceforth just card) has a slightly complex
structure, so we'll walk through it step-by-step.
lull.hoon defines a card like so:
+$ card (wind note gift)
A wind is defined in arvo.hoon as:
++ wind
|$ [a b]
$% [%pass p=wire q=a]
[%slip p=a]
[%give p=b]
==
Gall will not accept a %slip, so we can ignore that. A card, then, is one
of:
[%pass wire note]
[%give gift]
We'll consider each separately.
%pass
[%pass wire note]
The purpose of a %pass card is to send some kind of one-off request, action,
task, or what have you, to another agent or vane. A %pass card is a request
your agent initiates. This is in contrast to a %give card, which is
sent in response to another agent or vane.
The type of the first field in a %pass card is a wire. A wire is just a
list of @ta, with a syntax of /foo/bar/baz. When you %pass something to an
agent or vane, the response will come back on the wire you specify here. Your
agent can then check the wire and maybe do different things depending on its
content. The wire type is covered in
the types reference. We'll show how wires
are practically used later on.
The type of the next field is a note:agent:gall (henceforth just note), which
lull.hoon defines as:
+$ note
$% [%agent [=ship name=term] =task]
[%arvo note-arvo]
[%pyre =tang]
==
- An
%agentnoteis a request to another Gall agent, either local or on a remote ship. Theshipandnamefields are just the target ship and agent name. Thetaskis the request itself, we'll discuss it separately below. - An
%arvonoteis a request to a vane. We'll discuss such requests below. - A
%pyrenoteis used to abort an event. It's mostly used internally bykiln(a submodule of%hood), it's unlikely you'd use it in your own agent. Thetangcontains an error message.
task
A task:agent:gall (henceforth just task) is defined in lull.hoon as:
+$ task
$% [%watch =path]
[%watch-as =mark =path]
[%leave ~]
[%poke =cage]
[%poke-as =mark =cage]
==
Note a few of these include a path field. The path type is exactly the same
as a wire - a list of @ta with a syntax of /foo/bar/baz. The reason for
the wire/path distinction is just to indicate their separate purposes. While
a wire is for responses, a path is for requests. The
path type is also covered in the
types reference.
The kinds of tasks can be divided into two categories:
Subscriptions
%watch, %watch-as and %leave all pertain to subscriptions.
%watch: A request to subscribe to the specifiedpath. Once subscribed, your agent will receive any updates the other agent sends out on thatpath. You can subscribe more than once to the samepath, but each subscription must have a separatewirespecified at the beginning of the%passcard.%watch-as: This is the same as%watch, except Gall will convert updates to the givenmarkbefore delivering them to your agent.%leave: Unsubscribe. The subscription to cancel is determined by thewireat the beginning of thepasscard rather than the subscriptionpath, so its argument is just~.
Examples
Pokes
Pokes are requests, actions, or just some data which you send to another agent. Unlike subscriptions, these are just one-off messages.
A %poke contains a cage of some data. A cage is a cell of [mark vase].
The mark is just a @tas like %foo, and corresponds to a mark file in the
/mar directory. We'll cover marks in greater detail later. The vase contains
the actual data you're sending.
The %poke-as task is the same as %poke except Gall will convert the mark
in the cage to the mark you specify before sending it off.
Examples
note-arvo
A note-arvo is defined in lull.hoon like so:
+$ 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]
[%$ %whiz ~]
[@tas %meta vase]
==
The letter at the beginning corresponds to the vane - %b for Behn, %c for
Clay, etc. After then vane letter comes the task. Each vane has an API with a
set of tasks that it will accept, and are defined in each vane's section of
lull.hoon. Each vane's tasks are documented on the API Reference page of its
section in the Arvo documentation.
Examples
%give
[%give gift]
The purpose of a %give card is to respond to a request made by another agent
or vane. More specifically, it's either for acknowledging a request, or for
sending out updates to subscribers. This is in contrast to a %pass
card, which is essentially unsolicited.
A %give card contains a gift:agent:gall (henceforth just gift), which is
defined in lull.hoon as:
+$ gift
$% [%fact paths=(list path) =cage]
[%kick paths=(list path) ship=(unit ship)]
[%watch-ack p=(unit tang)]
[%poke-ack p=(unit tang)]
==
These can be divided into two categories:
Acknowledgements
%watch-ack is sent in response to a %watch or %watch-as request, and
%poke-ack is sent in response to a %poke or %poke-as request. If the
(unit tang) is null, it's an ack - a positive acknowledgement. If the (unit tang) is non-null, it's a nack - a negative acknowledgement, and the tang
contains an error message. Gall automatically sends a nack with a stack trace if
your agent crashes while processing the request, and automatically sends an ack
if it does not. Therefore, you would not explicitly produce a %watch-ack or
%poke-ack gift.
Examples
Subscriptions
%fact and %kick are both sent out to existing subscribers - entities that
have previously %watched a path on your ship.
A %kick gift takes a list of subscription paths. and a (unit ship), which
is the ship to kick from those paths. If the unit is null, all subscribers are
kicked from the specified paths. Note that sometimes Gall can produce %kick
gifts without your agent explicitly sending a card, due to networking
conditions.
%facts are how updates are sent out to subscribers. The paths field is a
list of subscription paths - all subscribers of the specified paths will
receive the %fact. The cage is the data itself - a cell of a mark and a
vase.
Examples
Summary
Here's a diagram that summarizes the different kinds of cards: