urbit/lib/tapp.hoon

411 lines
10 KiB
Plaintext
Raw Normal View History

2019-05-28 23:23:06 +03:00
/- tapp-sur=tapp
2019-06-01 00:44:47 +03:00
/+ async
2019-05-29 01:38:14 +03:00
|* $: state-type=mold
peek-data=mold
2019-05-29 03:11:21 +03:00
in-poke-data=mold
out-poke-data=mold
2019-05-29 01:38:14 +03:00
in-peer-data=mold
2019-05-29 03:11:21 +03:00
out-peer-data=mold
2019-05-29 01:38:14 +03:00
==
2019-05-23 22:26:53 +03:00
|%
2019-05-29 03:11:21 +03:00
++ tapp-sur (^tapp-sur out-poke-data out-peer-data)
2019-05-28 23:23:06 +03:00
++ card card:tapp-sur
++ sign sign:tapp-sur
++ contract contract:tapp-sur
2019-05-29 01:38:14 +03:00
++ command
$% [%init ~]
[%poke =in-poke-data]
2019-05-29 01:38:14 +03:00
[%peer =path]
[%diff =dock =path =in-peer-data]
2019-05-29 03:01:18 +03:00
[%take =sign]
2019-05-29 01:38:14 +03:00
==
2019-05-23 22:26:53 +03:00
::
2019-06-01 00:44:47 +03:00
++ async-lib (^async sign card contract)
++ async async:async-lib
2019-05-23 22:26:53 +03:00
::
+$ move (pair bone card)
2019-06-01 00:44:47 +03:00
++ tapp-async (async state-type)
2019-05-23 22:26:53 +03:00
+$ tapp-state
2019-05-29 01:38:14 +03:00
$: waiting=(qeu command)
2019-06-01 00:44:47 +03:00
active=(unit eval-form:eval:tapp-async)
2019-05-23 22:26:53 +03:00
app-state=state-type
==
+$ tapp-peek
[%noun ?(? (set contract))]
2019-05-29 01:38:14 +03:00
::
2019-06-04 01:25:15 +03:00
:: The form of a tapp
::
+$ tapp-core-all
$_ ^|
|_ [bowl:gall state-type]
::
:: Initialization
::
++ handle-init
*form:tapp-async
::
:: Input
::
++ handle-poke
|~ in-poke-data
*form:tapp-async
::
:: Read
::
++ handle-peek
|~ path
*(unit (unit peek-data))
::
:: Subscription request
::
++ handle-peer
|~ path
*form:tapp-async
::
:: Receive subscription result
::
++ handle-diff
|~ [dock path in-peer-data]
*form:tapp-async
::
:: Receive syscall result
::
++ handle-take
|~ sign
*form:tapp-async
--
::
:: Default handlers for all comands
::
++ default-tapp
^- tapp-core-all
|_ [bowl:gall state-type]
++ handle-init
*form:tapp-async
::
++ handle-poke
|=(* (async-fail:async-lib %no-poke-handler ~))
::
++ handle-peek _~
::
++ handle-peer
|= =path
~| %default-tapp-no-sole
?< ?=([%sole *] path)
(async-fail:async-lib %no-peer-handler >path< ~)
::
++ handle-diff
|=(* (async-fail:async-lib %no-diff-handler ~))
::
++ handle-take
|=(* (async-fail:async-lib %no-take-handler ~))
--
::
2019-05-29 01:38:14 +03:00
:: The form of a tapp that only handles pokes
::
++ tapp-core-poke
$_ ^|
|_ [bowl:gall state-type]
2019-06-04 01:25:15 +03:00
++ handle-poke handle-poke:*tapp-core-all
2019-05-29 01:38:14 +03:00
--
::
++ create-tapp-poke
|= handler=tapp-core-poke
%- create-tapp-poke-peer
|_ [=bowl:gall state=state-type]
2019-05-29 03:11:21 +03:00
++ handle-poke ~(handle-poke handler bowl state)
++ handle-peer handle-peer:default-tapp
2019-05-29 01:38:14 +03:00
--
::
:: The form of a tapp that only handles pokes and peers
::
++ tapp-core-poke-peer
$_ ^|
|_ [bowl:gall state-type]
2019-06-04 01:25:15 +03:00
++ handle-poke handle-poke:*tapp-core-all
++ handle-peer handle-peer:*tapp-core-all
2019-05-29 01:38:14 +03:00
--
::
++ create-tapp-poke-peer
|= handler=tapp-core-poke-peer
%- create-tapp-all
|_ [=bowl:gall state=state-type]
++ handle-init handle-init:default-tapp
2019-05-29 03:11:21 +03:00
++ handle-poke ~(handle-poke handler bowl state)
++ handle-peek handle-peek:default-tapp
2019-05-29 03:11:21 +03:00
++ handle-peer ~(handle-peer handler bowl state)
++ handle-diff handle-diff:default-tapp
++ handle-take handle-take:default-tapp
2019-05-29 01:38:14 +03:00
--
::
:: The form of a tapp that only handles pokes and diffs
::
++ tapp-core-poke-diff
$_ ^|
|_ [bowl:gall state-type]
2019-06-04 01:25:15 +03:00
++ handle-poke handle-poke:*tapp-core-all
++ handle-diff handle-diff:*tapp-core-all
2019-05-29 01:38:14 +03:00
--
::
++ create-tapp-poke-diff
|= handler=tapp-core-poke-diff
%- create-tapp-all
|_ [=bowl:gall state=state-type]
++ handle-init handle-init:default-tapp
2019-05-29 03:11:21 +03:00
++ handle-poke ~(handle-poke handler bowl state)
++ handle-peek handle-peek:default-tapp
++ handle-peer handle-peer:default-tapp
2019-05-29 03:11:21 +03:00
++ handle-diff ~(handle-diff handler bowl state)
++ handle-take handle-take:default-tapp
2019-05-29 03:01:18 +03:00
--
::
:: The form of a tapp that only handles pokes, peers, and takes
::
++ tapp-core-poke-peer-take
$_ ^|
|_ [bowl:gall state-type]
2019-06-04 01:25:15 +03:00
++ handle-poke handle-poke:*tapp-core-all
++ handle-peer handle-peer:*tapp-core-all
++ handle-take handle-take:*tapp-core-all
2019-05-29 03:01:18 +03:00
--
::
++ create-tapp-poke-peer-take
|= handler=tapp-core-poke-peer-take
%- create-tapp-all
|_ [=bowl:gall state=state-type]
++ handle-init handle-init:default-tapp
2019-05-29 03:11:21 +03:00
++ handle-poke ~(handle-poke handler bowl state)
++ handle-peek handle-peek:default-tapp
2019-05-29 03:11:21 +03:00
++ handle-peer ~(handle-peer handler bowl state)
++ handle-diff handle-diff:default-tapp
2019-05-29 03:11:21 +03:00
++ handle-take ~(handle-take handler bowl state)
2019-05-29 01:38:14 +03:00
--
::
:: The form of a tapp that only handles pokes, peers, diffs, and takes
::
++ tapp-core-poke-peer-diff-take
$_ ^|
|_ [bowl:gall state-type]
2019-06-04 01:25:15 +03:00
++ handle-poke handle-poke:*tapp-core-all
++ handle-peer handle-peer:*tapp-core-all
++ handle-diff handle-diff:*tapp-core-all
++ handle-take handle-take:*tapp-core-all
--
::
++ create-tapp-poke-peer-diff-take
|= handler=tapp-core-poke-peer-diff-take
%- create-tapp-all
|_ [=bowl:gall state=state-type]
++ handle-init handle-init:default-tapp
++ handle-poke ~(handle-poke handler bowl state)
++ handle-peek handle-peek:default-tapp
++ handle-peer ~(handle-peer handler bowl state)
++ handle-diff ~(handle-diff handler bowl state)
++ handle-take ~(handle-take handler bowl state)
--
::
2019-05-29 01:38:14 +03:00
++ create-tapp-all
|= handler=tapp-core-all
2019-05-23 22:26:53 +03:00
|_ [=bowl:gall tapp-state]
++ this-tapp .
2019-05-25 05:42:37 +03:00
++ prep
|= old-state=(unit)
2019-05-25 05:42:37 +03:00
^- (quip move _this-tapp)
?~ old-state
~& [%tapp-init dap.bowl]
=. waiting (~(put to waiting) %init ~)
start-async
::
=/ old ((soft tapp-state) u.old-state)
2019-05-25 05:42:37 +03:00
?~ old
~& [%tapp-reset dap.bowl]
2019-05-25 05:42:37 +03:00
`this-tapp
~& [%tapp-loaded dap.bowl]
2019-05-25 05:42:37 +03:00
`this-tapp(+<+ u.old)
2019-05-23 22:26:53 +03:00
::
:: Start a command
::
2019-05-29 02:06:53 +03:00
++ poke
2019-05-29 03:11:21 +03:00
|= =in-poke-data
2019-05-23 22:26:53 +03:00
^- (quip move _this-tapp)
2019-05-29 03:11:21 +03:00
=. waiting (~(put to waiting) %poke in-poke-data)
2019-05-23 22:26:53 +03:00
?^ active
2019-06-01 00:44:47 +03:00
~& [%waiting-until-current-async-finishes waiting]
2019-05-23 22:26:53 +03:00
`this-tapp
2019-06-01 00:44:47 +03:00
start-async
2019-05-23 22:26:53 +03:00
::
:: Read from tapp state
::
++ peek
|= =path
^- (unit (unit ?(tapp-peek peek-data)))
?- path
[%x %tapp %active ~]
[~ ~ %noun ?=(^ active)]
::
[%x %tapp %contracts ~]
[~ ~ %noun ?~(active ~ contracts.u.active)]
::
*
(~(handle-peek handler bowl app-state) path)
==
::
2019-05-29 01:38:14 +03:00
:: Receive subscription request
::
++ peer
|= =path
^- (quip move _this-tapp)
=. waiting (~(put to waiting) %peer path)
?^ active
`this-tapp
2019-06-01 00:44:47 +03:00
start-async
2019-05-29 01:38:14 +03:00
::
:: Receive subscription response
::
++ diff
|= [=wire =in-peer-data]
^- (quip move _this-tapp)
?> ?=([@ @ *] wire)
=/ her (slav %p i.wire)
=* app i.t.wire
=* pax t.t.wire
=. waiting (~(put to waiting) %diff [her app] pax in-peer-data)
?^ active
`this-tapp
2019-06-01 00:44:47 +03:00
start-async
2019-05-29 01:38:14 +03:00
::
2019-06-01 00:44:47 +03:00
:: Pass response to async
2019-05-23 22:26:53 +03:00
::
++ sigh-httr
|= [=wire =httr:eyre]
^- (quip move _this-tapp)
2019-06-01 00:44:47 +03:00
(take-async bowl `[wire %sigh httr])
2019-05-23 22:26:53 +03:00
::
:: Failed http request
::
++ sigh-tang
|= [=wire =tang]
^- (quip move _this-tapp)
2019-06-01 00:44:47 +03:00
(oob-fail-async %failed-sigh tang)
2019-05-23 22:26:53 +03:00
::
2019-05-29 03:01:18 +03:00
++ wake-note
2019-05-26 05:17:18 +03:00
|= [=wire error=(unit tang)]
^- (quip move _this-tapp)
?^ error
2019-06-01 00:44:47 +03:00
(oob-fail-async %timer-fire-failed u.error)
(take-async bowl `[wire %wake ~])
2019-05-26 05:17:18 +03:00
::
2019-05-29 03:01:18 +03:00
++ wake-effect
|= [=wire error=(unit tang)]
^- (quip move _this-tapp)
=. waiting (~(put to waiting) %take %wake error)
?^ active
`this-tapp
2019-06-01 00:44:47 +03:00
start-async
2019-05-29 03:01:18 +03:00
::
2019-06-01 00:44:47 +03:00
:: Continue computing async
2019-05-23 22:26:53 +03:00
::
2019-06-01 00:44:47 +03:00
++ take-async
|= =async-input:async-lib
2019-05-23 22:26:53 +03:00
^- (quip move _this-tapp)
2019-06-01 00:44:47 +03:00
=/ m tapp-async
2019-05-23 22:26:53 +03:00
?~ active
:: Can't cancel HTTP requests, so we might get answers after end
:: of computation
::
2019-06-01 00:44:47 +03:00
?: ?=([~ @ %sigh *] in.async-input)
`this-tapp
2019-06-01 00:44:47 +03:00
~| %no-active-async
~| ?~ in.async-input
2019-05-29 03:01:18 +03:00
~
2019-06-01 00:44:47 +03:00
wire.u.in.async-input
2019-05-29 03:01:18 +03:00
!!
2019-05-23 22:26:53 +03:00
=^ r=[moves=(list move) =eval-result:eval:m] u.active
2019-06-01 00:44:47 +03:00
(take:eval:m u.active ost.bowl async-input)
=> .(active `(unit eval-form:eval:tapp-async)`active) :: TMI
2019-05-23 22:26:53 +03:00
=^ moves=(list move) this-tapp
?- -.eval-result.r
%next `this-tapp
2019-06-01 00:44:47 +03:00
%fail (fail-async [contracts err]:eval-result.r)
%done (done-async [contracts value]:eval-result.r)
2019-05-23 22:26:53 +03:00
==
[(weld moves.r moves) this-tapp]
::
2019-06-01 00:44:47 +03:00
:: Fails currently-running async
::
2019-06-01 00:44:47 +03:00
++ oob-fail-async
(cury fail-async contracts:(need active))
::
2019-06-01 00:44:47 +03:00
:: Called on async failure
2019-05-23 22:26:53 +03:00
::
2019-06-01 00:44:47 +03:00
++ fail-async
|= [contracts=(set contract) err=(pair term tang)]
2019-05-23 22:26:53 +03:00
^- (quip move _this-tapp)
2019-05-29 01:38:14 +03:00
%- %- slog
:* leaf+(trip dap.bowl)
leaf+"tapp command failed"
leaf+(trip p.err)
q.err
==
2019-06-01 00:44:47 +03:00
(finish-async contracts)
2019-05-23 22:26:53 +03:00
::
2019-06-01 00:44:47 +03:00
:: Called on async success
2019-05-23 22:26:53 +03:00
::
2019-06-01 00:44:47 +03:00
++ done-async
|= [contracts=(set contract) state=state-type]
2019-05-23 22:26:53 +03:00
^- (quip move _this-tapp)
=. app-state state
2019-06-01 00:44:47 +03:00
(finish-async contracts)
2019-05-23 22:26:53 +03:00
::
2019-06-01 00:44:47 +03:00
:: Called whether async failed or succeeded
2019-05-23 22:26:53 +03:00
::
2019-06-01 00:44:47 +03:00
++ finish-async
|= contracts=(set contract)
2019-05-23 22:26:53 +03:00
^- (quip move _this-tapp)
=^ moves-1 this-tapp (cancel-contracts contracts)
2019-05-23 22:26:53 +03:00
=. active ~
=. waiting +:~(get to waiting)
2019-06-01 00:44:47 +03:00
=^ moves-2 this-tapp start-async
[(weld moves-1 moves-2) this-tapp]
::
2019-05-23 22:26:53 +03:00
:: Try to start next command
::
2019-06-01 00:44:47 +03:00
++ start-async
2019-05-23 22:26:53 +03:00
^- (quip move _this-tapp)
?. =(~ active)
2019-06-01 00:44:47 +03:00
~| %async-already-active !!
2019-05-29 01:38:14 +03:00
=/ next=(unit command) ~(top to waiting)
2019-05-23 22:26:53 +03:00
?~ next
`this-tapp
=. active
:- ~
2019-06-01 00:44:47 +03:00
%- from-form:eval:tapp-async
^- form:tapp-async
2019-05-29 01:38:14 +03:00
?- -.u.next
%init ~(handle-init handler bowl app-state)
2019-05-29 03:11:21 +03:00
%poke (~(handle-poke handler bowl app-state) +.u.next)
%peer (~(handle-peer handler bowl app-state) +.u.next)
2019-05-29 01:38:14 +03:00
%diff (~(handle-diff handler bowl app-state) +.u.next)
2019-05-29 03:01:18 +03:00
%take (~(handle-take handler bowl app-state) +.u.next)
2019-05-29 01:38:14 +03:00
==
2019-06-01 00:44:47 +03:00
(take-async bowl ~)
::
:: Cancel outstanding contracts
::
++ cancel-contracts
|= contracts=(set contract)
^- (quip move this-tapp)
[(zing (turn ~(tap in contracts) cancel-contract)) this-tapp]
::
:: Cancel individual contract
::
++ cancel-contract
|= =contract
^- (list move)
?- -.contract
2019-05-29 03:01:18 +03:00
%wait [ost.bowl %rest /note/(scot %da at.contract) at.contract]~
%hiss ~ :: can't cancel; will ignore response
==
2019-05-23 22:26:53 +03:00
--
--