on 514b5fc help sign in
145 lines 3.9 kB history raw
1+++
2title = "Start Thread"
3weight = 1
4template = "doc.html"
5+++
7Here's an example of a barebones gall agent that just starts a thread:
9#### `thread-starter.hoon`
11```hoon
12/+ default-agent, dbug
13=* card card:agent:gall
14%- agent:dbug
15^- agent:gall
16|_ =bowl:gall
17+* this .
18 def ~(. (default-agent this %|) bowl)
19::
20++ on-init on-init:def
21++ on-save on-save:def
22++ on-load on-load:def
23++ on-poke
24 |= [=mark =vase]
25 ^- (quip card _this)
26 ?+ mark (on-poke:def mark vase)
27 %noun
28 ?+ q.vase (on-poke:def mark vase)
29 (pair term term)
30 =/ tid `@ta`(cat 3 'thread_' (scot %uv (sham eny.bowl)))
31 =/ ta-now `@ta`(scot %da now.bowl)
32 =/ start-args [~ `tid byk.bowl p.q.vase !>(q.q.vase)]
33 :_ this
34 :~
35 [%pass /thread/[ta-now] %agent [our.bowl %spider] %poke %spider-start !>(start-args)]
36 ==
37 ==
38 ==
39++ on-watch on-watch:def
40++ on-leave on-leave:def
41++ on-peek on-peek:def
42++ on-agent
43 |= [=wire =sign:agent:gall]
44 ^- (quip card _this)
45 ?+ -.wire (on-agent:def wire sign)
46 %thread
47 ?+ -.sign (on-agent:def wire sign)
48 %poke-ack
49 ?~ p.sign
50 %- (slog leaf+"Thread started successfully" ~)
51 `this
52 %- (slog leaf+"Thread failed to start" u.p.sign)
53 `this
54 ==
55 ==
56++ on-arvo on-arvo:def
57++ on-fail on-fail:def
58--
59```
61And here's a minimal thread to test it with:
63#### `test-thread.hoon`
65```hoon
66/- spider
67=, strand=strand:spider
68^- thread:spider
69|= arg=vase
70=/ m (strand ,vase)
71^- form:m
72|= strand-input:strand
73?+ q.arg [~ %fail %not-foo ~]
74 %foo
75 [~ %done arg]
76==
77```
79Save them as `/app/thread-starter.hoon` and `/ted/test-thread.hoon` respectively in the `%base` desk, `|commit %base`, and start the app with `|rein %base [& %thread-starter]`.
81Now you can poke it with a pair of thread name and argument like:
83```
84:thread-starter [%test-thread %foo]
85```
87You should see `Thread started successfully`.
89Now try poking it with `[%fake-thread %foo]`, you should see something like:
91```
92Thread failed to start
93/app/spider/hoon:<[355 5].[355 60]>
94[%no-file-for-thread %fake-thread]
95/app/spider/hoon:<[354 5].[355 60]>
96/app/spider/hoon:<[353 3].[359 19]>
97/app/spider/hoon:<[350 3].[359 19]>
98/app/spider/hoon:<[346 3].[359 19]>
99/app/spider/hoon:<[343 3].[359 19]>
100/app/spider/hoon:<[341 3].[359 19]>
101/app/spider/hoon:<[340 3].[359 19]>
102/app/spider/hoon:<[336 3].[359 19]>
103/app/spider/hoon:<[335 3].[359 19]>
104/app/spider/hoon:<[202 24].[202 68]>
105/app/spider/hoon:<[200 7].[207 9]>
106/app/spider/hoon:<[199 5].[208 17]>
107/app/spider/hoon:<[197 5].[208 17]>
108/app/spider/hoon:<[196 5].[208 17]>
109/sys/vane/gall/hoon:<[1.370 9].[1.370 37]>
110```
112### Analysis
114We can ignore the input logic, here's the important part:
116```hoon
117=/ tid `@ta`(cat 3 'thread_' (scot %uv (sham eny.bowl)))
118=/ ta-now `@ta`(scot %da now.bowl)
119=/ start-args [~ `tid byk.bowl p.q.vase !>(q.q.vase)]
120:_ this
121:~
122 [%pass /thread/[ta-now] %agent [our.bowl %spider] %poke %spider-start !>(start-args)]
123==
124```
126You can generate a tid any way you like, just make sure it's unique. Here we just use the hash of some entropy prefixed with `thread_`.
128Then it's just a poke to `%spider` with the mark `%spider-start` and a vase containing [start-args](/docs/userspace/threads/reference#start-thread). Spider will then respond with a `%poke-ack` with a `(unit tang)` which will be `~` if it started successfully or else contain an error and a traceback if it failed. Here we test for this and print the result:
130```hoon
131++ on-agent
132 |= [=wire =sign:agent:gall]
133 ^- (quip card _this)
134 ?+ -.wire (on-agent:def wire sign)
135 %thread
136 ?+ -.sign (on-agent:def wire sign)
137 %poke-ack
138 ?~ p.sign
139 %- (slog leaf+"Thread started successfully" ~)
140 `this
141 %- (slog leaf+"Thread failed to start" u.p.sign)
142 `this
143 ==
144 ==
145```