This document describes the data types for Gall defined in
+$ bitt (map duct (pair ship path))
This is the structure Gall uses to keep track of subscribers to our Gall agent. The
sup field of a
bowl contains the
bitt for our agent.
+$ boat%+ map [=wire =ship =term][acked=? =path]
This is the structure Gall uses to keep track of subscriptions our agent has initiated. The
wex field of a
bowl contails the
boat for that agent.
wire field is the
sign:agents will come in on. The
term fields are the ship and the name of the agent to which our agent has subscribed.
acked field is
%.y if they have acknowledged our subscription request, and
%.n if they have not. The
path field is the
path on the other agent to which our agent has subscribed.
+$ bowl :: standard app state$: $: our=ship :: hostsrc=ship :: guestdap=term :: agent== ::$: wex=boat :: outgoing subssup=bitt :: incoming subs== ::$: act=@ud :: change numbereny=@uvJ :: entropynow=@da :: current timebyk=beak :: load source== == ::
Additional agent state.
bowl is given to the agent core each time an event comes in. The fields are as follows:
our: Our ship.
src: The ship from which the current request originated.
dap: The name of our agent.
wex: Outgoing subscriptions. That is, subscriptions our agent has initiated. See the
boatsection for details of the type.
sup: Incoming subscriptions. That is, subscriptions others have made to our agent. See the
bittsection for details of the type.
act: The total number of
moves our agent has processed so far.
eny: 512 bits of entropy.
now: The current date-time.
byk: The ship, desk and
casein Clay from which this agent was loaded. The
[%da @da]where the
@dais the when the agent was loaded. A
beakis a triple of
[ship desk case].
+$ dude term
+$ gill (pair ship term)
A general contact: A pair of the ship and agent name.
+$ scar$: p=@udq=(map duct bone)r=(map bone duct)==
Opaque duct - used internally.
+$ suss (trel dude @tas @da)
+$ well (pair desk term)
Desk and agent.
+$ neat$% [%arvo =note-arvo][%agent [=ship name=term] =deal][%pyre =tang]==
note:agent, except the
%agent case has a
deal instead of just a
task:agent. This is used for messages that come in over the network and would not be used manually.
+$ deal$% [%raw-poke =mark =noun]task:agent==
task:agent but with the additional case of a raw poke. This is used for messages that come in over the network and would not be used manually.
+$ unto$% [%raw-fact =mark =noun]sign:agent==
sign:agent but with the additional case of a raw fact. This is used for messages that come in over the network and would not be used manually.
++ agent=< form|%
Container for Gall agent types. The most significant arm is
form:agent, which specifies the structure of the agent itself. There are also some additional structures defined here, mostly defining the kinds of messages agents can send. The different arms of the core in
agent are considered separately below.
+$ step (quip card form)
A cell of
card:agents to be sent and a new agent state. This is the type returned by most arms of an agent. A
(quip a b) is the same as
[(list a) b], it's just a more convenient way to specify it.
+$ card (wind note gift)
An effect - typically a message to be sent to another agent or vane. A list of these are returned by most agent arms along with a new state in a
wind is the following:
++ wind|$ [a b]$% [%pass p=path q=a][%slip p=a][%give p=b]==
Gall will not allow a
%slip, so in practice a
card will be one of:
[%pass path note]
p specifies the
wire on which a response should be returned. See
gift:agent below for details of their types.
+$ note$% [%agent [=ship name=term] =task][%arvo note-arvo][%pyre =tang]==
The type for messages initiated by our agent. This is opposed to
gift:agent, which is the type for responding to other agents or vanes, or for sending out updates to subscribers. The three cases are:
%agent: Poke another agent, subscribe to another agent, or cancel a subscription to another agent. The
namefields are the ship and agent to which the
taskshould be sent. The
taskis the request itself, see
task:agentbelow for its possible types.
%arvo: Pass a
taskto a vane. The type of a
note-arvois:You can refer to the+$ 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][%$ %whiz ~][@tas %meta vase]==
/sys/lull.hoonsource code for all the possible vane tasks, or see each vane's API Reference section in the Arvo documentation
%pyre: This is for aborting side-effects initiated during agent installation. The
tangis an error message.
note:agent is always wrapped in a
+$ task$% [%watch =path][%watch-as =mark =path][%leave ~][%poke =cage][%poke-as =mark =cage]==
The types of messages initiated by our agent and sent to another agent. This is in contrast to
gift:agents, which are responses to incoming messages from agents or updates to agents already subscribed. The five kinds are:
%watch: Subscribe to
pathon the target ship and agent.
%watch-as: Same as
%watch, except you ask the target's Gall to convert subscription updates to the
markyou specified rather than just giving you the
markproduced by the agent.
%leave: Cancel subscription. The particular subscription to cancel will be determined by the
wiregiven in the
pfield of the containing
%poke: Poke the target ship and agent with the given
cage, which is a pair of
%poke-as: Same as
%poke, except the
cagewill be converted to the specified
task:agent is always wrapped in a
+$ gift$% [%fact paths=(list path) =cage][%kick paths=(list path) ship=(unit ship)][%watch-ack p=(unit tang)][%poke-ack p=(unit tang)]==
The types of messages our agent can either send in response to messages from other agents, or send to subscribed agents. This is in contrast to
task:agents, which are messages to other agents our agent initiates rather than sends in response. The four kinds are:
%fact: An update to existing subscribers. The
pathsfield specifies which subscription paths the update should go out to. The
cageis the data, and is a
%kick: Kick subscriber, ending their subscription. The
pathsfield specifies which paths the subscriber should be kicked from, and the
shipfield specifies the ship to kick. If the
shipfield is null, all subscribers on the specified paths are kicked. Gall will automatically remove the subscription from our agent's
map), and subscriber will no longer receive updates on the
paths in question.
%watch-ack: Acknowledge a subscription request. If
pis null, it's an ack (positive acknowledgement), and if
pis non-null, it's a nack (negative acknowledgement). Simply crashing will caused Gall to nack a subscription request, and not crashing but not explicitly producing a
giftwill cause Gall to ack a subscription request. Therefore, you'd typically only explicitly produce a
giftif you wanted to nack a subscription request with a custom error in the
%poke-ack: Acknowledge a poke. If
pis null, it's an ack, and if
pis non-null, it's a nack. Simply crashing will cause Gall to nack a poke, and not crashing but not explicitly producing a
giftwill cause Gall to ack a poke. Therefore, you'd typically only explicitly produce a
giftif you wanted to nack a poke with a custom error in the
gift:agent is always wrapped in a
+$ sign$% [%poke-ack p=(unit tang)][%watch-ack p=(unit tang)][%fact =cage][%kick ~]==
sign is like a
gift:agent but it's something that comes in to our agent from another agent rather than something we send out. The possible types are:
%poke-ack: Another agent has acked (positively acknowledged) or nacked (negatively acknowledged) a
task:agentwe previously sent. It's an ack if
pis null and a nack if
pis non-null. The
tangcontains an error or traceback if it's a nack.
%watch-ack: Another agent has acked or nacked a
task:agent(subscription request) we previously sent. It's an ack if
pis null and a nack if
pis non-null. The
tangcontains an error or traceback if it's a nack. If it's a nack, Gall will automatically remove the subscription from our agent's
boat(outbound subscription map).
%fact: An update from another agent to which we've previously subscribed with a
task:agent(subscription request). The
cagecontains the data, and is a
%kick: Our subscription to another agent has been ended, and we'll no longer receive updates. A
%kickmay be intentional, but it may also happen due to certain network conditions or other factors. As a result, it's best to try and resubscribe with another
task:agent, and if they nack the
%watch, we can conclude it was intentional and give up.
++ form$_ ^||_ bowl++ on-init*(quip card _^|(..on-init))::++ on-save*vase::++ on-load|~ old-state=vase*(quip card _^|(..on-init))::++ on-poke|~ [mark vase]*(quip card _^|(..on-init))::++ on-watch|~ path*(quip card _^|(..on-init))::++ on-leave|~ path*(quip card _^|(..on-init))::++ on-peek|~ path*(unit (unit cage))::++ on-agent|~ [wire sign]*(quip card _^|(..on-init))::++ on-arvo|~ [wire sign-arvo]*(quip card _^|(..on-init))::++ on-fail|~ [term tang]*(quip card _^|(..on-init))----
This defines the structure of the agent itself. The agent is a door with a
bowl as its sample and exactly ten arms. Below we'll describe each arm briefly.
- Accepts: Nothing.
This arm is called when the agent is initially installed.
This arm is called when another agent pokes our agent.
This arm is called when another agent subscribes to our agent.
This arm is called when another agent unsubscribes from a subscription path on our agent.
(unit (unit cage))
This arm is called when a scry is performed on our agent.
This arm is called when another agent give our agent a
This arm is called when a vane gives our agent a
+$ 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]==
You can refer to the
/sys/lull.hoon source code, or the API Reference of each vane in the Arvo documentation.
This arm is called if certain errors occur in Gall, such as if our agent tries to create a duplicate subscription.