<commit_before>+++
title = "6. Pokes"
weight = 30
template = "doc.html"
+++

In this lesson we'll look at sending and receiving one-off messages called
`%poke`s. We'll look at the `on-poke` agent arm which handles incoming pokes.
We'll also introduce the `on-agent` arm, and look at the one kind of response it can
take - a `%poke-ack`.

## Receiving a poke

Whenever something tries to poke your agent, Gall calls your agent's `on-poke`
arm and give it the `cage` from the poke as its sample. The `on-poke` arm will
produce a `(quip card _this)`. Here's how it would typically begin:

```hoon
++  on-poke
  |=  [=mark =vase]
  ^-  (quip card _this)
  ...
```

The sample of the gate is usually specified as a cell of `mark` and `vase`
rather than just `cage`, simply because it's easier to work with.

Typically, you'd first test the `mark` with something like a
[wutlus](/docs/hoon/reference/rune/wut#-wutlus) `?+` expression, passing
unexpected `mark`s to `default-agent`, which just crashes. We'll look at custom
`mark`s in a subsequent lesson, but the basic patten looks like:

```hoon
?+  mark  (on-poke:def mark vase)
  %noun            ...
  %something-else  ...
  ...
==
```

After testing the `mark`, you'd usually extract the `vase` to the expected type,
and then apply whatever logic you need. For example:

```hoon
=/  action  !<(some-type vase)
?-  -.action
  %foo  ...
  %bar  ...
  ...
==
```

Your agent will then produce a list of `card`s to be sent off and a new,
modified state, as appropriate. We'll go into subscriptions in the next lesson,
but just to give you an idea of a typical pattern: An agent for a chat app might
take new messages as pokes, add them to the list of messages in its state, and
send out the new messages to subscribed chat participants as `gift`s.

As discussed [in the previous
lesson](/docs/userspace/gall-guide/5-cards#acknowledgements), Gall will
automatically send a `%poke-ack` `gift` back to wherever the poke came from. The
`%poke-ack` will be a nack if your agent crashed while processing the poke, and
an ack otherwise. If it's a nack, the `tang` in the `%poke-ack` will contain a
stack trace of the crash.

As a result, you do not need to explicitly send a `%poke-ack`. Instead, you
would design your agent to handle only what you expect and crash in all other
cases. You can crash by passing the `cage` to `default-agent`, or just with a
`!!`. In the latter case, if you want to add an error message to the stack
trace, you can do so like:

```hoon
~|  "some error message"
!!
```

This will produce a trace that looks something like:

```
/sys/vane/gall/hoon:<[1.372 9].[1.372 37]>
/app/pokeme/hoon:<[31 3].[43 5]>
/app/pokeme/hoon:<[32 3].[43 5]>
/app/pokeme/hoon:<[34 5].[42 7]>
/app/pokeme/hoon:<[35 5].[42 7]>
/app/pokeme/hoon:<[38 7].[41 27]>
/app/pokeme/hoon:<[39 9].[40 11]><commit_msg>gall-guide: pokes - remove link to previous lesson<commit_after>+++
title = "6. Pokes"
weight = 30
template = "doc.html"
+++

In this lesson we'll look at sending and receiving one-off messages called
`%poke`s. We'll look at the `on-poke` agent arm which handles incoming pokes.
We'll also introduce the `on-agent` arm, and look at the one kind of response it can
take - a `%poke-ack`.

## Receiving a poke

Whenever something tries to poke your agent, Gall calls your agent's `on-poke`
arm and give it the `cage` from the poke as its sample. The `on-poke` arm will
produce a `(quip card _this)`. Here's how it would typically begin:

```hoon
++  on-poke
  |=  [=mark =vase]
  ^-  (quip card _this)
  ...
```

The sample of the gate is usually specified as a cell of `mark` and `vase`
rather than just `cage`, simply because it's easier to work with.

Typically, you'd first test the `mark` with something like a
[wutlus](/docs/hoon/reference/rune/wut#-wutlus) `?+` expression, passing
unexpected `mark`s to `default-agent`, which just crashes. We'll look at custom
`mark`s in a subsequent lesson, but the basic patten looks like:

```hoon
?+  mark  (on-poke:def mark vase)
  %noun            ...
  %something-else  ...
  ...
==
```

After testing the `mark`, you'd usually extract the `vase` to the expected type,
and then apply whatever logic you need. For example:

```hoon
=/  action  !<(some-type vase)
?-  -.action
  %foo  ...
  %bar  ...
  ...
==
```

Your agent will then produce a list of `card`s to be sent off and a new,
modified state, as appropriate. We'll go into subscriptions in the next lesson,
but just to give you an idea of a typical pattern: An agent for a chat app might
take new messages as pokes, add them to the list of messages in its state, and
send out the new messages to subscribed chat participants as `gift`s.

As discussed in the previous lesson, Gall will automatically send a `%poke-ack`
`gift` back to wherever the poke came from. The `%poke-ack` will be a nack if
your agent crashed while processing the poke, and an ack otherwise. If it's a
nack, the `tang` in the `%poke-ack` will contain a stack trace of the crash.

As a result, you do not need to explicitly send a `%poke-ack`. Instead, you
would design your agent to handle only what you expect and crash in all other
cases. You can crash by passing the `cage` to `default-agent`, or just with a
`!!`. In the latter case, if you want to add an error message to the stack
trace, you can do so like:

```hoon
~|  "some error message"
!!
```

This will produce a trace that looks something like:

```
/sys/vane/gall/hoon:<[1.372 9].[1.372 37]>
/app/pokeme/hoon:<[31 3].[43 5]>
/app/pokeme/hoon:<[32 3].[43 5]>
/app/pokeme/hoon:<[34 5].[42 7]>
/app/pokeme/hoon:<[35 5].[42 7]>
/app/pokeme/hoon:<[38 7].[41 27]>
/app/pokeme/hoon:<[39 9].[40 11]>
{'fraction_non_alphanumeric': 0.12280084447572133, 'fraction_numerical': 0.01847290640394089, 'mean_word_length': 3.6294788273615635, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2484122', 'n_tokens_mistral': 2072, 'n_tokens_neox': 1909, 'n_words': 851}