7Here's a simple example of a thread that starts another thread:
14=, strand=strand:spider
19;< tid=tid:spider bind:m (start-thread %child)
28=, strand=strand:spider
37Save `parent.hoon` and `child.hoon` in `/ted` of the `%base` desk, `|commit %base` and run `-parent`. You should see something like:
45`parent.hoon` just uses the `strandio` function `start-thread` to start `child.hoon`, and `child.hoon` just prints `foo` to the dojo. Since we got `foo` we can tell the second thread did, in fact, run.
48;< tid=tid:spider bind:m (start-thread %child)
51See here how we gave `start-thread` the name of the thread to run. It returns the `tid` of the thread, which we could then use to poke it or whatever.
53`start-thread` handles creating the `tid` for the thread so is quite convenient.
55Note that threads we start this way will be a child of the thread that started them, and so will be killed when the parent thread ends.
57## Start thread and get its result
59If we want to actually get the result of the thread we started, it's slightly more complicated:
66=, strand=strand:spider
71;< =bowl:spider bind:m get-bowl
72=/ tid `@ta`(cat 3 'strand_' (scot %uv (sham %child eny.bowl)))
73;< ~ bind:m (watch-our /awaiting/[tid] %spider /thread-result/[tid])
74;< ~ bind:m %- poke-our
77 !>([`tid.bowl `tid byk.bowl %child !>(~)])
79;< =cage bind:m (take-fact /awaiting/[tid])
80;< ~ bind:m (take-kick /awaiting/[tid])
81?+ p.cage ~|([%strange-thread-result p.cage %child tid] !!)
82 %thread-done (pure:m q.cage)
83 %thread-fail (strand-fail !<([term tang] q.cage))
92=, strand=strand:spider
95++ url "https://www.whatsthelatestbasehash.com/"
101;< =cord bind:m (fetch-cord url)
102=/ hash-as-cord `@t`(end [3 (sub (met 3 cord) 1)] cord)
103=/ hash `@uv`(slav %uv hash-as-cord)
107`child.hoon` simply grabs the latest base hash from https://www.whatsthelatestbasehash.com/ and returns it.
109`parent.hoon` is a bit more complicated so we'll look at it line-by-line
112;< =bowl:spider bind:m get-bowl
115First we grab the bowl
118=/ tid `@ta`(cat 3 'strand_' (scot %uv (sham %child eny.bowl)))
121Then we generate a `tid` (thread ID) for the thread we're gonna start
124;< ~ bind:m (watch-our /awaiting/[tid] %spider /thread-result/[tid])
127We pre-emptively subscribe for the result. Spider sends the result at `/thread-result/<tid>` so that's where we subscribe.
130;< ~ bind:m %- poke-our
133 !>([`tid.bowl byk.bowl `tid %child !>(~)])
137Spider takes a poke with a mark %spider-start and a vase containing `[parent=(unit tid) use=(unit tid) =beak file=term =vase]` to start a thread, where:
139- `parent` is an optional parent thread. In this case we say the parent is our tid. Specifying a parent means the child will be killed if the parent ends.
140- `use` is the thread ID for the thread we're creating
141- `beak` is a `[p=ship q=desk r=case]` triple which specifies the desk and revision containing the thread we want to run. In this case we just use `byk.bowl`.
142- `file` is the filename of the thread we want to start
143- `vase` is the vase it will be given as an argument when it's started
146;< =cage bind:m (take-fact /awaiting/[tid])
149We wait for a fact which will be the result of the thread.
152;< ~ bind:m (take-kick /awaiting/[tid])
155Spider will kick us from the subscription when it ends the thread so we also take that kick.
158?+ p.cage ~|([%strange-thread-result p.cage %child tid] !!)
159 %thread-done (pure:m q.cage)
160 %thread-fail (strand-fail !<([term tang] q.cage))
164Finally we test whether the thread produced a `%thread-done` or a `%thread-fail`. These are the two possible marks produced by spider when it returns the results of a thread. A `%thread-done` will contain a vase with the result, and a `%thread-fail` will contain an error message and traceback, so we see which it is and then either produce the result with `pure` or trigger a `%thread-fail` with the error we got from the child.
173=, strand=strand:spider
178;< =bowl:spider bind:m get-bowl
179=/ tid `@ta`(cat 3 'strand_' (scot %uv (sham %child eny.bowl)))
180%- (slog leaf+"Starting child thread..." ~)
181;< ~ bind:m %- poke-our
184 !>([`tid.bowl byk.bowl `tid %child !>(~)])
186;< ~ bind:m (sleep ~s5)
187%- (slog leaf+"Stopping child thread..." ~)
188;< ~ bind:m %- poke-our
193;< ~ bind:m (sleep ~s2)
202=, strand=strand:spider
211 ;< ~ bind:m (sleep `@dr`(div ~s1 2))
212 %- (slog leaf+"child thread" ~)
224`child.hoon` just prints to the dojo in a loop.
226`parent.hoon` starts `child.hoon`, and then pokes spider like:
229;< ~ bind:m %- poke-our
236- `%spider-stop` is the mark that tells spider to kill a thread.
237- `tid` is the tid of the thread to kill
238- `%.y` tells spider to suppress traceback in the result of the killed thread. If you give it `%.n` it will include the traceback.
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list