urbit/lib/tapp.hoon
2019-05-28 13:23:06 -07:00

167 lines
4.1 KiB
Plaintext

/- tapp-sur=tapp
/+ trad
|* [state-type=mold command-type=mold poke-data=mold]
|%
++ tapp-sur (^tapp-sur poke-data)
++ card card:tapp-sur
++ sign sign:tapp-sur
++ contract contract:tapp-sur
::
:: The form of a tapp
::
++ tapp-core
$_ ^|
|_ [bowl:gall state-type]
++ handle-command
|~ command-type
*form:tapp-trad
--
::
++ trad-lib (^trad sign card contract)
++ trad trad:trad-lib
::
+$ move (pair bone card)
++ tapp-trad (trad state-type)
+$ tapp-state
$: waiting=(qeu command-type)
active=(unit eval-form:eval:tapp-trad)
app-state=state-type
==
++ create-tapp
|= handler=tapp-core
|_ [=bowl:gall tapp-state]
++ this-tapp .
++ prep
|= old-state=*
^- (quip move _this-tapp)
~& [%tapp-loaded dap.bowl]
=/ old ((soft tapp-state) old-state)
?~ old
`this-tapp
`this-tapp(+<+ u.old)
::
:: Start a command
::
++ poke-noun
|= command=command-type
^- (quip move _this-tapp)
=. waiting (~(put to waiting) command)
?^ active
~& [%waiting-until-current-trad-finishes waiting]
`this-tapp
start-trad
::
:: Pass response to trad
::
++ sigh-httr
|= [=wire =httr:eyre]
^- (quip move _this-tapp)
(take-trad bowl `[wire %sigh httr])
::
:: Failed http request
::
++ sigh-tang
|= [=wire =tang]
^- (quip move _this-tapp)
(oob-fail-trad %failed-sigh tang)
::
++ wake
|= [=wire error=(unit tang)]
^- (quip move _this-tapp)
?^ error
(oob-fail-trad %timer-fire-failed u.error)
(take-trad bowl `[wire %wake ~])
::
:: Continue computing trad
::
++ take-trad
|= =trad-input:trad-lib
^- (quip move _this-tapp)
=/ m tapp-trad
?~ active
:: Can't cancel HTTP requests, so we might get answers after end
:: of computation
::
?: ?=([~ @ %sigh *] in.trad-input)
`this-tapp
~| %no-active-trad !!
=^ r=[moves=(list move) =eval-result:eval:m] u.active
(take:eval:m u.active ost.bowl trad-input)
=> .(active `(unit eval-form:eval:tapp-trad)`active) :: TMI
=^ moves=(list move) this-tapp
?- -.eval-result.r
%next `this-tapp
%fail (fail-trad [contracts err]:eval-result.r)
%done (done-trad [contracts value]:eval-result.r)
==
[(weld moves.r moves) this-tapp]
::
:: Fails currently-running trad
::
++ oob-fail-trad
(cury fail-trad contracts:(need active))
::
:: Called on trad failure
::
++ fail-trad
|= [contracts=(set contract) err=(pair term tang)]
^- (quip move _this-tapp)
%- (slog leaf+"tapp command failed" leaf+(trip p.err) q.err)
(finish-trad contracts)
::
:: Called on trad success
::
++ done-trad
|= [contracts=(set contract) state=state-type]
^- (quip move _this-tapp)
=. app-state state
(finish-trad contracts)
::
:: Called whether trad failed or succeeded
::
++ finish-trad
|= contracts=(set contract)
^- (quip move _this-tapp)
=^ moves-1 this-tapp (cancel-contracts contracts)
=. active ~
=. waiting +:~(get to waiting)
=^ moves-2 this-tapp start-trad
[(weld moves-1 moves-2) this-tapp]
::
::
:: Try to start next command
::
++ start-trad
^- (quip move _this-tapp)
?. =(~ active)
~| %trad-already-active !!
=/ next=(unit command-type) ~(top to waiting)
?~ next
`this-tapp
=. active
:- ~
^- eval-form:eval:tapp-trad
%- from-form:eval:tapp-trad
^- form:tapp-trad
(~(handle-command handler bowl app-state) u.next)
(take-trad 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
%wait [ost.bowl %rest /(scot %da at.contract) at.contract]~
%hiss ~ :: can't cancel; will ignore response
==
--
--