@@ -5,10 +5,10 @@ template = "doc.html"
5aliases = ["/docs/learn/hoon/hoon-tutorial/gall/"]
5aliases = ["/docs/learn/hoon/hoon-tutorial/gall/"]
8−> Note: This guide is outdated. For an updated explanation of Gall, take a look at [/tutorial/arvo/gall](/docs/tutorials/arvo/gall)
10Gall is the Arvo vane responsible for handling user space applications. When writing a Gall application there are several things you will need to understand.
8Gall is the Arvo vane responsible for handling user space applications. When writing a Gall application there are several things you will need to understand.
10+For another explanation of Gall, take a look at [/tutorial/arvo/gall](/docs/tutorials/arvo/gall)
12## bowl and moves
12## bowl and moves
14The [core](/docs/glossary/core/) of a gall app is a [door](/docs/glossary/door/) which has two parts of its subject, the first a `bowl:gall` which contains a lot of standard things used by gall apps, the second a type containing app state information.
14The [core](/docs/glossary/core/) of a gall app is a [door](/docs/glossary/door/) which has two parts of its subject, the first a `bowl:gall` which contains a lot of standard things used by gall apps, the second a type containing app state information.
@@ -34,50 +34,98 @@ Each `card` is a pair of a tag and a [noun](/docs/glossary/noun/). The tag indic
35Gall applications can have a number of arms that get called depending on the information they are sent.
35Gall applications can have a number of arms that get called depending on the information they are sent.
37−### ++prep
37+This arm is called once when the agent is started. It has no input and
38+lets you perform any initial IO.
39−`++prep` is the arm that is called when an application is first started or when it's updated. This arm should be a [gate](/docs/glossary/gate/) that takes a `unit` of a noun and provides a way, if necessary, to make any changes to the application's data required by an upgrade. As a reminder, a `unit` is a type that may contain another type or it might contain `~`. They are used when there may or may not be some data available.
40+### +on-init
41−Often when developing an application you will not initially care about the data. Here is a sample `++prep` arm that will simply throw away the previous application state.
42+This arm is called when the app is initially started.
43−```hoon
44+### +on-save
45− |= a=(unit *)
46+This arm is called immediately before the agent is upgraded. It
46− `(quip move _+>.$)`[~ +>.$]
47+packages the permament state of the agent in a `vase` for the next version
47−```
48+of the agent. Unlike most handlers, this cannot produce effects.
52+This arm is called immediately after the agent is upgraded. It receives
53+a `vase` of the state of the previously running version of the agent,
54+which allows it to cleanly upgrade from the old agent.
58+This arm is called when the agent is "poked". The input is a `cage`, so
59+it's a pair of a mark and a dynamic `vase`.
49−### ++poke
63+This arm is called when a program wants to subscribe to the agent on a
64+particular `path`. The agent may or may not need to perform setup steps
65+to intialize the subscription. It may produce a `%give`
66+`%subscription-result` to the subscriber to get it up to date, but after
67+this event is complete, it cannot give further updates to a specific
68+subscriber. It must give all further updates to all subscribers on a
51−`++poke` is one of the primary arms used when building a Gall application. A `poke` is often a request to perform some operation that the application was designed for. These are requests from outside the application. `++poke` will get called with the raw noun data which can then be inspected to perform the requested actions with.
71+If this arm crashes, then the subscription is immediately terminated.
72+More specifcally, it never started -- the subscriber will receive a
73+negative `%watch-ack`. You may also produce an explicit `%kick` to
74+close the subscription without crashing -- for example, you could
75+produce a single update followed by a `%kick`.
53−Many arms, `++poke` included, have variants that end in the name of a mark e.g. `++poke-noun`. Which one gets called will be based on which mark was used to create the poke. Gall will attempt to use the most specific arm it can find, eventually falling back to `++poke` if no matching mark arm is found. Use of these mark arms, however, is now discouraged.
77+### +on-leave
55−### ++coup
79+This arm is called when a program becomes unsubscribed to you.
80+Subscriptions may close because the subscriber intentionally
81+unsubscribed, but they also could be closed by an intermediary. For
82+example, if a subscription is from another ship which is currently
83+unreachable, Ames may choose to close the subscription to avoid queueing
84+updates indefinitely. If the program crashes while processing an
85+update, this may also generate an unsubscription. You should consider
86+subscriptions to be closable at any time.
57−`++coup` is a response handler for any pokes our application sent out.
88+### +on-peek
59−### ++peer
90+This arm is called when a program reads from the agent's "scry"
91+namespace, which should be referentially transparent. Unlike most
92+handlers, this cannot perform IO, and it cannot change the state. All
93+it can do is produce a piece of data to the caller, or not.
61−`++peer` is used to handle subscriptions. When something subscribes to your application this arm will run. The something could be another Gall application on your ship or another ship or a tile from landscape or anything else that is able to communicate with Gall. Your outgoing subscriptions will not be tracked automatically but incoming ones will live in `sup.bowl` so that you can send information to them when required.
95+If this arm produces `[~ ~ data]`, then `data` is the value at the the
96+given `path`. If it produces `[~ ~]`, then there is no data at the given
97+`path` and never will be. If it produces `~`, then we don't know yet
98+whether there is or will be data at the given `path`.
63−### ++pull
100+### +on-agent
65−`++pull` is run when someone unsubscribes from your application, this is used to run any changes needed for your application when they unsubscribed. Their removal from `sup.bowl` is handled for you.
102+This arm is called to handle responses to `%give` moves to other agents.
103+It will be one of the following types of response:
67−### ++quit
105+- `%poke-ack`: acknowledgment (positive or negative) of a poke. If the
106+ value is `~`, then the poke succeeded. If the value is `[~ tang]`,
107+ then the poke failed, and a printable explanation (e.g. a stack trace)
108+ is given in the `tang`.
69−`++quit` gets called when a subscription is dropped. Often you will just want to resubscribe when this happens.
110+- `%watch-ack`: acknowledgment (positive or negative) of a subscription.
111+ If negative, the subscription is already ended (technically, it never
71−### ++reap
114+- `%fact`: update from the publisher.
73−`++reap` is to `++peer` as `++coup` is to `++poke`, that is to say it's the arm that gets run in acknowledgment of outgoing subscription requests.
116+- `%kick`: notification that the subscription has ended.
75−### ++diff
118+### +on-arvo
77−`++diff` gets called when an application you are subscribed to has an update. It could either be an entirely new set of data for that application or an update to existing data.
120+This arm is called to handle responses to `%pass` `move`s to vanes. The
121+list of possible responses from the system is statically defined in
122+sys/zuse.hoon (grep for `+ sign-arvo`).
79−### ++sigh
124+### +on-fail
81−`++sigh` gets called when Eyre has a response to an http request made by our application.
126+If an error happens in `+on-poke`, the crash report goes into the
127+`%poke-ack` response. Similarly, if an error happens in
128+`+on-subscription`, the crash report goes into the `%watch-ack`
129+response. If a crash happens in any of the other handlers, the report
130+is passed into this arm.
83−Let's take a look in the next section at an example Gall app.