urbit/pkg/arvo/app/spider.hoon

654 lines
17 KiB
Plaintext
Raw Normal View History

2019-09-26 22:00:11 +03:00
/- spider
2021-09-26 02:45:05 +03:00
/+ libstrand=strand, default-agent, verb, server, dbug
=, strand=strand:libstrand
~% %spider-top ..part ~
2019-09-26 07:12:58 +03:00
|%
2019-11-19 07:36:21 +03:00
+$ card card:agent:gall
+$ thread thread:spider
+$ tid tid:spider
+$ input input:spider
+$ yarn (list tid)
+$ thread-form _*eval-form:eval:(strand ,vase)
+$ trying ?(%build %none)
+$ state
$: starting=(map yarn [=trying =vase])
running=(axal thread-form)
tid=(map tid yarn)
serving=(map tid [(unit @ta) =mark =desk])
scries=(map tid [=ship =path])
2019-11-10 10:27:07 +03:00
==
::
2020-06-18 06:31:37 +03:00
+$ clean-slate-any
$^ clean-slate-ket
$% clean-slate-sig
clean-slate-1
2021-09-13 14:01:42 +03:00
clean-slate-2
2021-09-26 02:45:05 +03:00
clean-slate-3
clean-slate-4
2020-06-18 06:31:37 +03:00
clean-slate
==
::
2019-11-10 10:27:07 +03:00
+$ clean-slate
$: %5
starting=(map yarn [=trying =vase])
running=(list yarn)
tid=(map tid yarn)
serving=(map tid [(unit @ta) =mark =desk])
scries=(map tid [ship path])
==
::
+$ clean-slate-4
2021-09-26 02:45:05 +03:00
$: %4
starting=(map yarn [=trying =vase])
running=(list yarn)
tid=(map tid yarn)
serving=(map tid [(unit @ta) =mark =desk])
==
::
+$ clean-slate-3
2021-09-13 14:01:42 +03:00
$: %3
starting=(map yarn [=trying =vase])
running=(list yarn)
tid=(map tid yarn)
serving=(map tid [@ta =mark =desk])
==
::
+$ clean-slate-2
$: %2
2020-06-18 06:31:37 +03:00
starting=(map yarn [=trying =vase])
running=(list yarn)
tid=(map tid yarn)
2020-09-03 07:47:34 +03:00
serving=(map tid [@ta =mark])
2020-06-18 06:31:37 +03:00
==
::
+$ clean-slate-1
$: %1
starting=(map yarn [=trying =vase])
running=(list yarn)
tid=(map tid yarn)
==
::
2020-06-18 06:31:37 +03:00
+$ clean-slate-ket
$: starting=(map yarn [trying=?(%build %find %none) =vase])
running=(list yarn)
tid=(map tid yarn)
==
::
+$ clean-slate-sig
$: starting=~
running=(list yarn)
tid=(map tid yarn)
2019-11-10 10:27:07 +03:00
==
--
::
2021-09-26 02:45:05 +03:00
%- agent:dbug
2019-11-19 07:36:21 +03:00
^- agent:gall
2019-11-07 09:19:32 +03:00
=| =state
=<
2019-11-15 23:46:11 +03:00
%+ verb |
~% %spider-agent ..bind-eyre ~
2019-11-19 07:36:21 +03:00
|_ =bowl:gall
2019-11-10 10:27:07 +03:00
+* this .
2019-11-07 09:19:32 +03:00
spider-core +>
2019-11-10 10:27:07 +03:00
sc ~(. spider-core bowl)
def ~(. (default-agent this %|) bowl)
bec byk.bowl(r da+now.bowl)
2019-09-26 07:12:58 +03:00
::
2021-09-26 02:45:05 +03:00
++ on-init
2020-09-03 07:47:34 +03:00
^- (quip card _this)
:_ this
~[bind-eyre:sc]
2019-11-10 10:27:07 +03:00
++ on-save clean-state:sc
++ on-load
2020-06-18 06:31:37 +03:00
|^
|= old-state=vase
2020-06-18 06:31:37 +03:00
=+ !<(any=clean-slate-any old-state)
=? any ?=(^ -.any) (old-to-1 any)
=? any ?=(~ -.any) (old-to-1 any)
2021-09-26 02:45:05 +03:00
=^ upgrade-cards any
(old-to-2 any)
2021-09-13 14:01:42 +03:00
=. any (old-to-3 any)
2021-09-26 02:45:05 +03:00
=. any (old-to-4 any)
=. any (old-to-5 any)
?> ?=(%5 -.any)
2020-06-18 06:31:37 +03:00
::
=. tid.state tid.any
=/ yarns=(list yarn)
2020-06-18 06:31:37 +03:00
%+ welp running.any
~(tap in ~(key by starting.any))
|- ^- (quip card _this)
?~ yarns
[~[bind-eyre:sc] this]
2019-11-10 10:27:07 +03:00
=^ cards-1 state
(handle-stop-thread:sc (yarn-to-tid i.yarns) |)
2019-11-10 10:27:07 +03:00
=^ cards-2 this
$(yarns t.yarns)
[:(weld upgrade-cards cards-1 cards-2) this]
2020-06-18 06:31:37 +03:00
::
++ old-to-1
|= old=clean-slate-ket
^- clean-slate-1
2020-06-18 06:31:37 +03:00
1+old(starting (~(run by starting.old) |=([* v=vase] none+v)))
::
++ old-to-2
|= old=clean-slate-any
2021-09-13 14:01:42 +03:00
^- (quip card clean-slate-any)
?> ?=(?(%1 %2 %3 %4 %5) -.old)
?: ?=(?(%2 %3 %4 %5) -.old)
`old
:- ~[bind-eyre:sc]
:* %2
starting.old
running.old
tid.old
~
==
2021-09-13 14:01:42 +03:00
::
++ old-to-3
|= old=clean-slate-any
2021-09-26 02:45:05 +03:00
^- clean-slate-any
?> ?=(?(%2 %3 %4 %5) -.old)
?: ?=(?(%3 %4 %5) -.old)
2021-09-13 14:01:42 +03:00
old
:* %3
starting.old
running.old
tid.old
(~(run by serving.old) |=([id=@ta =mark] [id mark q.byk.bowl]))
==
2021-09-26 02:45:05 +03:00
++ old-to-4
|= old=clean-slate-any
^- clean-slate-any
?> ?=(?(%3 %4 %5) -.old)
?: ?=(?(%4 %5) -.old)
2021-09-26 02:45:05 +03:00
old
:* %4
starting.old
running.old
tid.old
(~(run by serving.old) |=([id=@ta =mark =desk] [`id mark q.byk.bowl]))
==
::
++ old-to-5
|= old=clean-slate-any
^- clean-slate
?> ?=(?(%4 %5) -.old)
?: ?=(%5 -.old) old
[%5 +.old(serving [serving.old ~])]
2020-06-18 06:31:37 +03:00
--
::
2019-11-07 09:19:32 +03:00
++ on-poke
~/ %on-poke
2019-09-26 07:12:58 +03:00
|= [=mark =vase]
^- (quip card _this)
?: ?=(%spider-kill mark)
(on-load on-save)
2019-09-26 07:12:58 +03:00
=^ cards state
2019-11-07 09:19:32 +03:00
?+ mark (on-poke:def mark vase)
2022-08-30 07:09:08 +03:00
%spider-input (on-poke-input:sc !<(input vase))
%spider-start (handle-start-thread:sc !<(start-args:spider vase))
%spider-inline (handle-inline-thread:sc !<(inline-args:spider vase))
%spider-stop (handle-stop-thread:sc !<([tid ?] vase))
2021-09-26 02:45:05 +03:00
%handle-http-request
2020-09-03 07:47:34 +03:00
(handle-http-request:sc !<([@ta =inbound-request:eyre] vase))
2019-09-26 07:12:58 +03:00
==
[cards this]
::
2019-11-07 09:19:32 +03:00
++ on-watch
~/ %on-watch
2019-10-11 01:30:24 +03:00
|= =path
^- (quip card _this)
=^ cards state
2019-11-07 09:19:32 +03:00
?+ path (on-watch:def path)
[%thread @ *] (on-watch:sc t.path)
[%thread-result @ ~] (on-watch-result:sc i.t.path)
2020-09-03 07:47:34 +03:00
[%http-response *] `state
2019-10-11 01:30:24 +03:00
==
[cards this]
::
2019-11-07 09:19:32 +03:00
++ on-leave on-leave:def
++ on-peek
~/ %on-peek
2019-09-29 07:44:31 +03:00
|= =path
^- (unit (unit cage))
2019-11-10 10:27:07 +03:00
?+ path (on-peek:def path)
[%x %tree ~]
2022-04-23 03:55:42 +03:00
``noun+!>((turn ~(tap of running.state) head))
2019-11-10 10:27:07 +03:00
::
[%x %starting @ ~]
2022-04-23 03:55:42 +03:00
``noun+!>((~(has of running.state) (~(got by tid.state) i.t.t.path)))
2019-11-10 10:27:07 +03:00
::
[%x %saxo @ ~]
``noun+!>((~(got by tid.state) i.t.t.path))
2019-09-29 07:44:31 +03:00
==
::
2019-11-07 09:19:32 +03:00
++ on-agent
~/ %on-agent
2019-11-19 07:36:21 +03:00
|= [=wire =sign:agent:gall]
2019-09-29 07:44:31 +03:00
^- (quip card _this)
=^ cards state
?+ wire !!
[%thread @ *] (on-agent:sc i.t.wire t.t.wire sign)
2019-09-29 07:44:31 +03:00
==
[cards this]
::
2019-11-07 09:19:32 +03:00
++ on-arvo
~/ %on-arvo
2019-09-26 07:12:58 +03:00
|= [=wire =sign-arvo]
^- (quip card _this)
=^ cards state
2019-11-07 09:19:32 +03:00
?+ wire (on-arvo:def wire sign-arvo)
[%thread @ *] (handle-sign:sc i.t.wire t.t.wire sign-arvo)
[%build @ ~] (handle-build:sc i.t.wire sign-arvo)
[%bind ~] `state
2019-09-26 07:12:58 +03:00
==
[cards this]
:: On unexpected failure, kill all outstanding strands
2019-09-29 07:44:31 +03:00
::
++ on-fail
|= [=term =tang]
^- (quip card _this)
%- (slog leaf+"spider crashed, killing all strands: {<term>}" tang)
(on-load on-save)
2019-09-26 07:12:58 +03:00
--
::
~% %spider-helper ..card ~
2019-11-19 07:36:21 +03:00
|_ =bowl:gall
++ bec `beak`byk.bowl(r da+now.bowl)
++ bind-eyre
^- card
[%pass /bind %arvo %e %connect [~ /spider] %spider]
::
++ new-thread-id
|= file=term
:((cury cat 3) file '--' (scot %uv (sham eny.bowl)))
::
2020-09-03 07:47:34 +03:00
++ handle-http-request
~/ %handle-http-request
2020-09-03 07:47:34 +03:00
|= [eyre-id=@ta =inbound-request:eyre]
^- (quip card _state)
::?> authenticated.inbound-request
2021-09-26 02:45:05 +03:00
=/ url
2020-09-03 07:47:34 +03:00
(parse-request-line:server url.request.inbound-request)
?> ?=([%spider @t @t @t @t ~] site.url)
=* desk i.t.site.url
=* input-mark i.t.t.site.url
=* thread i.t.t.t.site.url
=* output-mark i.t.t.t.t.site.url
=/ =tid (new-thread-id thread)
2020-09-03 07:47:34 +03:00
=. serving.state
(~(put by serving.state) tid [`eyre-id output-mark desk])
:: TODO: speed this up somehow. we spend about 15ms in this arm alone
::
=/ tube (convert-tube %json input-mark desk bowl)
2020-09-03 07:47:34 +03:00
?> ?=(^ body.request.inbound-request)
=/ body=json (need (de-json:html q.u.body.request.inbound-request))
=/ input=vase (slop !>(~) (tube !>(body)))
=/ boc bec
=/ =start-args:spider [~ `tid boc(q desk, r da+now.bowl) thread input]
(handle-start-thread start-args)
2020-09-03 07:47:34 +03:00
::
++ on-poke-input
|= input
=/ yarn (~(got by tid.state) tid)
(take-input yarn ~ %poke cage)
2019-09-26 07:12:58 +03:00
::
2019-11-07 09:19:32 +03:00
++ on-watch
|= [=tid =path]
(take-input (~(got by tid.state) tid) ~ %watch path)
2019-10-11 01:30:24 +03:00
::
++ on-watch-result
|= =tid
^- (quip card ^state)
`state
::
2019-09-26 07:12:58 +03:00
++ handle-sign
~/ %handle-sign
|= [=tid =wire =sign-arvo]
=/ yarn (~(get by tid.state) tid)
?~ yarn
%- (slog leaf+"spider got sign for non-existent {<tid>}" ~)
2019-11-10 10:27:07 +03:00
`state
(take-input u.yarn ~ %sign wire sign-arvo)
2019-09-26 07:12:58 +03:00
::
2019-11-07 09:19:32 +03:00
++ on-agent
2019-11-19 07:36:21 +03:00
|= [=tid =wire =sign:agent:gall]
=/ yarn (~(get by tid.state) tid)
?~ yarn
%- (slog leaf+"spider got agent for non-existent {<tid>}" ~)
2019-11-10 10:27:07 +03:00
`state
(take-input u.yarn ~ %agent wire sign)
2019-09-29 07:44:31 +03:00
::
++ handle-start-thread
~/ %handle-start-thread
|= [parent-tid=(unit tid) use=(unit tid) =beak file=term =vase]
2022-08-30 07:09:08 +03:00
(prep-thread parent-tid use beak %| file vase)
::
++ handle-inline-thread
~/ %handle-inline-thread
khan: support inline threads This allows you to pass a thread directly into khan, instead of passing a filename. This has several implications: - The friction for using threads from an app is significantly lower. Consider: =/ shed =/ m (strand ,vase) ;< ~ bind:m (poke:strandio [our %hood] %helm-hi !>('hi')) ;< ~ bind:m (poke:strandio [our %hood] %helm-hi !>('there')) (pure:m !>('product')) [%pass /wire %arvo %k %lard %base shed] - These threads close over their subject, so you don't need to parse arguments out from a vase -- you can just refer to them. The produced value must still be a vase. ++ hi-ship |= [=ship msg1=@t msg2=@t] =/ shed =/ m (strand ,vase) ;< ~ bind:m (poke:strandio [ship %hood] %helm-hi !>(msg1)) ;< ~ bind:m (poke:strandio [ship %hood] %helm-hi !>(msg2)) (pure:m !>('product')) [%pass /wire %arvo %k %lard %base shed] - Inline threads can be added to the dojo, though this PR does not add any sugar for this. =strandio -build-file %/lib/strandio/hoon =sh |= message=@t =/ m (strand:rand ,vase) ;< ~ bind:m (poke:strandio [our %hood] %helm-hi !>('hi')) ;< ~ bind:m (poke:strandio [our %hood] %helm-hi !>(message)) (pure:m !>('product')) |pass [%k %lard %base (sh 'the message')] Implementation notes: - Review the commits separately: the first is small and implements the real feature. The second moves the strand types into lull so khan can refer to them. - In lull, I wanted to put +rand inside +khan, but this fails to that issue that puts the compiler in a loop. +rand depends on +gall, which depends on +sign-arvo, which depends on +khan. If +rand is in +khan, this spins the compiler. The usual solution is to either move everything into the same battery (very ugly here) or break the recursion (which we do here).
2022-08-30 07:35:14 +03:00
|= [parent-tid=(unit tid) use=(unit tid) =beak =shed:khan]
(prep-thread parent-tid use beak %& shed)
2022-08-30 07:09:08 +03:00
::
++ prep-thread
|= $: parent-tid=(unit tid) use=(unit tid) =beak
khan: support inline threads This allows you to pass a thread directly into khan, instead of passing a filename. This has several implications: - The friction for using threads from an app is significantly lower. Consider: =/ shed =/ m (strand ,vase) ;< ~ bind:m (poke:strandio [our %hood] %helm-hi !>('hi')) ;< ~ bind:m (poke:strandio [our %hood] %helm-hi !>('there')) (pure:m !>('product')) [%pass /wire %arvo %k %lard %base shed] - These threads close over their subject, so you don't need to parse arguments out from a vase -- you can just refer to them. The produced value must still be a vase. ++ hi-ship |= [=ship msg1=@t msg2=@t] =/ shed =/ m (strand ,vase) ;< ~ bind:m (poke:strandio [ship %hood] %helm-hi !>(msg1)) ;< ~ bind:m (poke:strandio [ship %hood] %helm-hi !>(msg2)) (pure:m !>('product')) [%pass /wire %arvo %k %lard %base shed] - Inline threads can be added to the dojo, though this PR does not add any sugar for this. =strandio -build-file %/lib/strandio/hoon =sh |= message=@t =/ m (strand:rand ,vase) ;< ~ bind:m (poke:strandio [our %hood] %helm-hi !>('hi')) ;< ~ bind:m (poke:strandio [our %hood] %helm-hi !>(message)) (pure:m !>('product')) |pass [%k %lard %base (sh 'the message')] Implementation notes: - Review the commits separately: the first is small and implements the real feature. The second moves the strand types into lull so khan can refer to them. - In lull, I wanted to put +rand inside +khan, but this fails to that issue that puts the compiler in a loop. +rand depends on +gall, which depends on +sign-arvo, which depends on +khan. If +rand is in +khan, this spins the compiler. The usual solution is to either move everything into the same battery (very ugly here) or break the recursion (which we do here).
2022-08-30 07:35:14 +03:00
source=(each shed:khan [file=term =vase])
2022-08-30 07:09:08 +03:00
==
2019-09-26 07:12:58 +03:00
^- (quip card ^state)
=/ parent-yarn=yarn
?~ parent-tid
2019-11-10 10:27:07 +03:00
/
(~(got by tid.state) u.parent-tid)
2022-08-30 07:09:08 +03:00
=/ new-tid
?^ use
u.use
%- new-thread-id
?- -.source
%& (cat 3 'inline-' q.beak)
%| file.p.source
==
::
=/ =yarn (snoc parent-yarn new-tid)
2019-11-10 10:27:07 +03:00
::
2022-04-23 03:55:42 +03:00
?: (~(has of running.state) yarn)
~| [%already-started yarn]
2019-09-26 07:12:58 +03:00
!!
?: (~(has by starting.state) yarn)
~| [%already-starting yarn]
!!
2019-11-12 08:36:32 +03:00
::
=? serving.state !(~(has by serving.state) new-tid)
(~(put by serving.state) new-tid [~ %noun q.beak])
::
2022-08-30 07:09:08 +03:00
=. tid.state (~(put by tid.state) new-tid yarn)
?- -.source
2022-10-27 08:09:53 +03:00
%& (begin-shed yarn p.source)
2022-08-30 07:09:08 +03:00
%|
=. starting.state (~(put by starting.state) yarn [%build vase.p.source])
=/ pax=path
~| no-file-for-thread+file.p.source
(need (get-fit:clay beak %ted file.p.source))
:: ad-hoc to work only with the -keen/-pine threads -- pine uses keen
:: XX test -pine
:: XX TODO: expand to any thread that performs a remote scry request? how?
::
=? scries.state ?=(?([%ted %keen *] [%ted %pine *]) pax)
=+ !<([~ =ship =path] vase.p.source)
(~(put by scries.state) new-tid ship path)
2022-08-30 07:09:08 +03:00
:_ state
:_ ~
:+ %pass /build/[new-tid]
[%arvo %c %warp p.beak q.beak ~ %sing %a r.beak pax]
2021-09-27 01:30:12 +03:00
==
2019-09-26 22:00:11 +03:00
::
++ handle-build
~/ %handle-build
|= [=tid =sign-arvo]
2019-09-26 22:00:11 +03:00
^- (quip card ^state)
=/ =yarn (~(got by tid.state) tid)
=. starting.state
(~(jab by starting.state) yarn |=([=trying =vase] [%none vase]))
2020-04-21 08:05:05 +03:00
~| sign+[- +<]:sign-arvo
2020-12-08 03:22:26 +03:00
?> ?=([?(%behn %clay) %writ *] sign-arvo)
2020-04-21 08:05:05 +03:00
=/ =riot:clay p.sign-arvo
?~ riot
(thread-fail-not-running tid %build-thread-error *tang)
?. ?=(%vase p.r.u.riot)
(thread-fail-not-running tid %build-thread-strange >[p q]:u.riot< ~)
=/ maybe-thread (mule |.(!<(thread !<(vase q.r.u.riot))))
?: ?=(%| -.maybe-thread)
(thread-fail-not-running tid %thread-not-thread ~)
2022-10-27 08:09:53 +03:00
(slam-thread yarn p.maybe-thread)
::
2022-10-27 08:09:53 +03:00
++ slam-thread
~/ %slam-thread
|= [=yarn =thread]
2019-09-26 22:00:11 +03:00
^- (quip card ^state)
=/ =vase vase:(~(got by starting.state) yarn)
=/ res (mule |.((thread vase)))
?: ?=(%| -.res)
(thread-fail-not-running (yarn-to-tid yarn) %false-start p.res)
2022-08-30 07:09:08 +03:00
=. starting.state (~(del by starting.state) yarn)
2022-10-27 08:09:53 +03:00
(begin-shed yarn p.res)
2022-08-30 07:09:08 +03:00
::
2022-10-27 08:09:53 +03:00
++ begin-shed
khan: support inline threads This allows you to pass a thread directly into khan, instead of passing a filename. This has several implications: - The friction for using threads from an app is significantly lower. Consider: =/ shed =/ m (strand ,vase) ;< ~ bind:m (poke:strandio [our %hood] %helm-hi !>('hi')) ;< ~ bind:m (poke:strandio [our %hood] %helm-hi !>('there')) (pure:m !>('product')) [%pass /wire %arvo %k %lard %base shed] - These threads close over their subject, so you don't need to parse arguments out from a vase -- you can just refer to them. The produced value must still be a vase. ++ hi-ship |= [=ship msg1=@t msg2=@t] =/ shed =/ m (strand ,vase) ;< ~ bind:m (poke:strandio [ship %hood] %helm-hi !>(msg1)) ;< ~ bind:m (poke:strandio [ship %hood] %helm-hi !>(msg2)) (pure:m !>('product')) [%pass /wire %arvo %k %lard %base shed] - Inline threads can be added to the dojo, though this PR does not add any sugar for this. =strandio -build-file %/lib/strandio/hoon =sh |= message=@t =/ m (strand:rand ,vase) ;< ~ bind:m (poke:strandio [our %hood] %helm-hi !>('hi')) ;< ~ bind:m (poke:strandio [our %hood] %helm-hi !>(message)) (pure:m !>('product')) |pass [%k %lard %base (sh 'the message')] Implementation notes: - Review the commits separately: the first is small and implements the real feature. The second moves the strand types into lull so khan can refer to them. - In lull, I wanted to put +rand inside +khan, but this fails to that issue that puts the compiler in a loop. +rand depends on +gall, which depends on +sign-arvo, which depends on +khan. If +rand is in +khan, this spins the compiler. The usual solution is to either move everything into the same battery (very ugly here) or break the recursion (which we do here).
2022-08-30 07:35:14 +03:00
|= [=yarn =shed:khan]
2022-08-30 07:09:08 +03:00
?< (~(has of running.state) yarn)
=/ m (strand ,vase)
khan: support inline threads This allows you to pass a thread directly into khan, instead of passing a filename. This has several implications: - The friction for using threads from an app is significantly lower. Consider: =/ shed =/ m (strand ,vase) ;< ~ bind:m (poke:strandio [our %hood] %helm-hi !>('hi')) ;< ~ bind:m (poke:strandio [our %hood] %helm-hi !>('there')) (pure:m !>('product')) [%pass /wire %arvo %k %lard %base shed] - These threads close over their subject, so you don't need to parse arguments out from a vase -- you can just refer to them. The produced value must still be a vase. ++ hi-ship |= [=ship msg1=@t msg2=@t] =/ shed =/ m (strand ,vase) ;< ~ bind:m (poke:strandio [ship %hood] %helm-hi !>(msg1)) ;< ~ bind:m (poke:strandio [ship %hood] %helm-hi !>(msg2)) (pure:m !>('product')) [%pass /wire %arvo %k %lard %base shed] - Inline threads can be added to the dojo, though this PR does not add any sugar for this. =strandio -build-file %/lib/strandio/hoon =sh |= message=@t =/ m (strand:rand ,vase) ;< ~ bind:m (poke:strandio [our %hood] %helm-hi !>('hi')) ;< ~ bind:m (poke:strandio [our %hood] %helm-hi !>(message)) (pure:m !>('product')) |pass [%k %lard %base (sh 'the message')] Implementation notes: - Review the commits separately: the first is small and implements the real feature. The second moves the strand types into lull so khan can refer to them. - In lull, I wanted to put +rand inside +khan, but this fails to that issue that puts the compiler in a loop. +rand depends on +gall, which depends on +sign-arvo, which depends on +khan. If +rand is in +khan, this spins the compiler. The usual solution is to either move everything into the same battery (very ugly here) or break the recursion (which we do here).
2022-08-30 07:35:14 +03:00
=/ =eval-form:eval:m (from-form:eval:m shed)
2022-08-30 07:09:08 +03:00
=. running.state (~(put of running.state) yarn eval-form)
(take-input yarn ~)
2019-09-26 07:12:58 +03:00
::
++ handle-stop-thread
|= [=tid nice=?]
2019-09-29 07:44:31 +03:00
^- (quip card ^state)
=/ yarn=(unit yarn) (~(get by tid.state) tid)
?~ yarn
~& %stopping-nonexistent-thread
[~ state]
2022-04-23 03:55:42 +03:00
?: (~(has of running.state) u.yarn)
?. nice
(thread-fail u.yarn %cancelled ~)
=^ cancel-cards state (cancel-scry tid)
=^ done-cards state (thread-done u.yarn *vase)
[(weld cancel-cards done-cards) state]
?: (~(has by starting.state) u.yarn)
(thread-fail-not-running tid %stopped-before-started ~)
~& [%thread-not-started u.yarn]
2019-12-01 06:38:43 +03:00
?: nice
(thread-done u.yarn *vase)
(thread-fail u.yarn %cancelled ~)
2019-09-29 07:44:31 +03:00
::
2019-09-26 07:12:58 +03:00
++ take-input
~/ %take-input
|= [=yarn input=(unit input:strand)]
2019-09-26 07:12:58 +03:00
^- (quip card ^state)
=/ m (strand ,vase)
2022-04-23 03:55:42 +03:00
?. (~(has of running.state) yarn)
%- (slog leaf+"spider got input for non-existent {<yarn>}" ~)
`state
2019-09-26 07:12:58 +03:00
=/ =eval-form:eval:m
2022-04-23 03:55:42 +03:00
(need fil:(~(dip of running.state) yarn))
2019-09-26 07:12:58 +03:00
=| cards=(list card)
|- ^- (quip card ^state)
=^ r=[cards=(list card) =eval-result:eval:m] eval-form
=/ out
%- mule |.
(take:eval:m eval-form (convert-bowl yarn bowl) input)
2019-09-26 07:12:58 +03:00
?- -.out
%& p.out
%| [[~ [%fail %crash p.out]] eval-form]
==
2022-04-23 03:55:42 +03:00
=. running.state (~(put of running.state) yarn eval-form)
=/ =tid (yarn-to-tid yarn)
2019-09-26 07:12:58 +03:00
=. cards.r
%+ turn cards.r
|= =card
^- ^card
?+ card card
[%pass * *] [%pass [%thread tid p.card] q.card]
[%give ?(%fact %kick) *]
=- card(paths.p -)
%+ turn paths.p.card
|= =path
^- ^path
[%thread tid path]
2019-09-26 07:12:58 +03:00
==
=. cards (weld cards cards.r)
=^ final-cards=(list card) state
?- -.eval-result.r
%next `state
%fail (thread-fail yarn err.eval-result.r)
%done (thread-done yarn value.eval-result.r)
2019-09-26 07:12:58 +03:00
==
[(weld cards final-cards) state]
::
++ thread-fail-not-running
|= [=tid =term =tang]
2020-06-18 06:31:37 +03:00
^- (quip card ^state)
=/ =yarn (~(got by tid.state) tid)
2020-06-18 06:31:37 +03:00
:_ state(starting (~(del by starting.state) yarn))
=/ moz (thread-say-fail tid term tang)
?. ?=([~ %build *] (~(get by starting.state) yarn))
moz
:_(moz [%pass /build/[tid] %arvo %c %warp our.bowl %base ~])
::
++ thread-say-fail
|= [=tid =term =tang]
^- (list card)
:~ [%give %fact ~[/thread-result/[tid]] %thread-fail !>([term tang])]
[%give %kick ~[/thread-result/[tid]] ~]
==
::
++ cancel-scry
|= =tid
^- (quip card _state)
?~ scry=(~(get by scries.state) tid)
`state
:_ state(scries (~(del by scries.state) tid))
::%- (slog leaf+"cancelling {<tid>}: [{<[ship path]:u.scry>}]" ~)
[%pass /thread/[tid]/keen %arvo %a %yawn [ship path]:u.scry]~
::
2020-09-03 07:47:34 +03:00
++ thread-http-fail
|= [=tid =term =tang]
^- (quip card ^state)
=- (fall - `state)
2021-09-26 02:45:05 +03:00
%+ bind
2020-09-03 07:47:34 +03:00
(~(get by serving.state) tid)
2021-09-26 02:45:05 +03:00
|= [eyre-id=(unit @ta) output=mark =desk]
2020-09-03 07:47:34 +03:00
:_ state(serving (~(del by serving.state) tid))
2021-09-27 23:51:33 +03:00
?~ eyre-id
2021-09-28 05:09:35 +03:00
~
2021-09-27 23:51:33 +03:00
%+ give-simple-payload:app:server u.eyre-id
2020-09-03 07:47:34 +03:00
^- simple-payload:http
2020-09-11 06:08:16 +03:00
:_ ~ :_ ~
?. ?=(http-error:spider term)
((slog tang) 500)
?- term
%bad-request 400
%forbidden 403
%nonexistent 404
%offline 504
==
::
++ thread-fail
|= [=yarn =term =tang]
2019-09-26 07:12:58 +03:00
^- (quip card ^state)
::%- (slog leaf+"strand {<yarn>} failed" leaf+<term> tang)
=/ =tid (yarn-to-tid yarn)
=/ fail-cards (thread-say-fail tid term tang)
=^ cards state (thread-clean yarn)
2020-09-03 07:47:34 +03:00
=^ http-cards state (thread-http-fail tid term tang)
=^ scry-card state (cancel-scry tid)
:_ state
:(weld fail-cards cards http-cards scry-card)
2020-09-03 07:47:34 +03:00
::
++ thread-http-response
|= [=tid =vase]
^- (quip card ^state)
=- (fall - `state)
2021-09-26 02:45:05 +03:00
%+ bind
2020-09-03 07:47:34 +03:00
(~(get by serving.state) tid)
|= [eyre-id=(unit @ta) output=mark =desk]
2021-09-27 23:51:33 +03:00
?~ eyre-id
`state
=/ tube (convert-tube output %json desk bowl)
2021-09-26 02:45:05 +03:00
:_ state(serving (~(del by serving.state) tid))
2021-09-27 23:51:33 +03:00
%+ give-simple-payload:app:server u.eyre-id
2021-09-26 02:45:05 +03:00
(json-response:gen:server !<(json (tube vase)))
2019-09-26 07:12:58 +03:00
::
++ thread-done
|= [=yarn =vase]
2019-09-26 07:12:58 +03:00
^- (quip card ^state)
:: %- (slog leaf+"strand {<yarn>} finished" (sell vase) ~)
=/ =tid (yarn-to-tid yarn)
=/ done-cards=(list card)
:~ [%give %fact ~[/thread-result/[tid]] %thread-done vase]
[%give %kick ~[/thread-result/[tid]] ~]
==
2020-09-03 07:47:34 +03:00
=^ http-cards state
(thread-http-response tid vase)
=^ scry-card state (cancel-scry tid)
=^ cards state (thread-clean yarn)
[:(weld done-cards cards http-cards scry-card) state]
::
++ thread-clean
|= =yarn
^- (quip card ^state)
=/ children=(list ^yarn)
%+ turn
2022-04-23 03:55:42 +03:00
~(tap of (~(dip of running.state) yarn))
|= [child=^yarn *]
(welp yarn child)
2019-11-10 10:27:07 +03:00
|- ^- (quip card ^state)
?~ children
`state
=^ cards-children state $(children t.children)
=^ cards-our state
=/ =^yarn i.children
=/ =tid (yarn-to-tid yarn)
2022-04-23 03:55:42 +03:00
=: running.state (~(lop of running.state) yarn)
tid.state (~(del by tid.state) tid)
serving.state (~(del by serving.state) (yarn-to-tid yarn))
==
2019-11-10 10:27:07 +03:00
:_ state
%+ murn ~(tap by wex.bowl)
|= [[=wire =ship =term] [acked=? =path]]
^- (unit card)
?. ?& ?=([%thread @ *] wire)
=(tid i.t.wire)
2019-11-10 10:27:07 +03:00
==
~
`[%pass wire %agent [ship term] %leave ~]
[(welp cards-children cards-our) state]
::
++ convert-bowl
2019-11-19 07:36:21 +03:00
|= [=yarn =bowl:gall]
2019-11-10 10:27:07 +03:00
^- bowl:spider
:* our.bowl
2021-09-26 02:45:05 +03:00
src.bowl
(yarn-to-tid yarn)
(yarn-to-parent yarn)
2019-11-10 10:27:07 +03:00
wex.bowl
sup.bowl
eny.bowl
now.bowl
(yarn-to-byk yarn bowl)
2019-11-10 10:27:07 +03:00
==
::
++ yarn-to-tid
|= =yarn
^- tid
=/ nary (flop yarn)
?> ?=([@ *] nary)
i.nary
::
++ yarn-to-parent
|= =yarn
^- (unit tid)
=/ nary (flop yarn)
?> ?=([@ *] nary)
?~ t.nary
~
`i.t.nary
2019-11-10 10:27:07 +03:00
::
++ yarn-to-byk
2021-09-26 02:45:05 +03:00
|= [=yarn =bowl:gall]
2021-09-28 05:09:35 +03:00
=/ [* * =desk]
~| "no desk associated with {<tid>}"
%- ~(got by serving.state) (yarn-to-tid yarn)
=/ boc bec
boc(q desk)
::
2019-11-10 10:27:07 +03:00
++ clean-state
!> ^- clean-slate
5+state(running (turn ~(tap of running.state) head))
::
++ convert-tube
2021-09-26 02:45:05 +03:00
|= [from=mark to=mark =desk =bowl:gall]
.^
tube:clay
%cc
/(scot %p our.bowl)/[desk]/(scot %da now.bowl)/[from]/[to]
==
2019-09-26 07:12:58 +03:00
--