mirror of
https://github.com/urbit/shrub.git
synced 2024-12-14 11:08:45 +03:00
Merge branch 'test' of https://github.com/urbit/urbit into test
Conflicts: urb/urbit.pill
This commit is contained in:
commit
60fa9821e5
@ -126,9 +126,9 @@
|
||||
?~(nao ~ [~ (~(read-at-aeon ze lim dom ran) u.nao mun)])
|
||||
::
|
||||
++ balk :: read and send
|
||||
|= [hen=duct oan=@ud mun=mood]
|
||||
|= [hen=duct yon=@ud mun=mood]
|
||||
^+ +>
|
||||
=+ vid=(~(read-at-aeon ze lim dom ran) oan mun)
|
||||
=+ vid=(~(read-at-aeon ze lim dom ran) yon mun)
|
||||
?~ vid (blub hen) (blab hen mun u.vid)
|
||||
::
|
||||
++ blab :: ship result
|
||||
@ -338,8 +338,9 @@
|
||||
=+ nex=(~(get by haw.u.ref) nez)
|
||||
?~ nex +>+.^$
|
||||
?~ u.nex +>+.^$ :: should never happen
|
||||
=. +>+.^$ =+ roo=(edis ((hard nako) u.u.nex))
|
||||
?>(?=(^ ref.roo) roo)
|
||||
=. +>+.^$
|
||||
=+ roo=(edis ((hard nako) u.u.nex))
|
||||
?>(?=(^ ref.roo) roo)
|
||||
%= $
|
||||
haw.u.ref (~(del by haw.u.ref) nez)
|
||||
==
|
||||
@ -397,7 +398,7 @@
|
||||
..wake =- (blub:- p.i.xiq)
|
||||
=+ ^= ear
|
||||
(~(lobes-at-path ze lim dom ran) u.huy r.p.q.i.xiq)
|
||||
?: =(s.p.q.i.xiq ear) ..wake
|
||||
?: =(s.p.q.i.xiq ear) (blub p.i.xiq)
|
||||
=+ fud=(~(make-nako ze lim dom ran) u.nab u.huy)
|
||||
(bleb p.i.xiq +(u.nab) fud)
|
||||
==
|
||||
|
@ -773,69 +773,11 @@
|
||||
==
|
||||
::
|
||||
^= fac
|
||||
0w89.wgGV4.jAl90.00003.sV4OG.IJjfa.1vYpi.gRxB9.3m6kA.dopig.
|
||||
RxB93.m6kAd.opigR.xB93m.6kAdo.pigRx.B93m6.kAdop.igRxB.93m6k.
|
||||
Adopi.gRxBf.vGSfy.m8hQj.T-DiD.7kqvH.vEpA3.3vH-C.in~Tq.l8U0n.
|
||||
1FVhj.w9E1A.NIF6w.4j9v~.VZ0~B.9flkB.IY90B.-ieSV.Ky8Q~.4~07s.
|
||||
JcXFC.DtI-1.GGz-1.V-olV.g3wsv.ZCQM1.BJbVj.Vwiv0.uo7Gh.4qsxA.
|
||||
92ZYU.tJ5uH.yiIzV.FwvJR.UUq6z.cpKIG.Hck9v.qGDm1.PY2rM.itxLB.
|
||||
fn0Bo.5DO8x.oO7KE.kYh-P.NiKp1.HT88j.Mu3ZK.ciKsU.TnlkV.0Zo77.
|
||||
12ciy.nY3dM.7nDnY.GVgGh.ZllpO.SFHFb.p1Ae0.uUpXV.eqFvS.pkBRl.
|
||||
jv0MP.ilRHP.1HwtK.GFptt.2KdpP.RsYqI.wRHEG.j~LZQ.I06qJ.fP0Pp.
|
||||
77qjo.s0PU0.rGGg6.lgNvc.~CZE~.bSp9j.EGHF~.UqYB6.l4Y~Z.P~GGE.
|
||||
LwrJs.ZvYV-.U4Wh4.04dws.6HeuZ.2ZF7A.y4MN5.3vsCj.QHzjW.4lflk.
|
||||
WU6X0.AmMws.vbMfB.3e1s~.aeE7W.0hQPH.ODvMf.cvgzb.Y15Ah.01384.
|
||||
YwVPT.KzILB.PlaqN.pNlvw.fdQ79.~mPpo.YaHqw.fnWGB.QYM4F.w3E0b.
|
||||
0o~n-.faydD.zlllI.0nU3D.w5rlI.4nrSG.VkhPM.NTkpa.eoXzw.9AEYN.
|
||||
auZGt.99gxL.8RlsI.aXMXX.tFVhX.V4kj8.yczjh.faRI3.JTg1H.-0uZM.
|
||||
JA6rR.z0~pO.uXiSg.rvU27.A58MU.TBijQ.23F1J.CCIYE.IO8w-.cMlMA.
|
||||
hvKh4.zY16M.gjRlk.v--9h.TNNRR.HhIGo.8kZXk.Wb74j.faHlk.6V-Vw.
|
||||
jMan8.yb37R.Q2h42.Or3Nw.Pp39w.jZ--3.-jwZH.U~3Za.Uu0u6.bNAOP.
|
||||
U2jux.Jqo2R.O8x1~.ecZvL.30ug~.qpoFw.vwtqD.Vb6EI.cZQyO.EN-xl.
|
||||
nlsLC.dT099.apOh5.SEeDz.07-GE.xFzZk.KcmCl.SJWF5.v3u1x.Uq1Cj.
|
||||
tV~hG.YuGGb.SgpdR.xHaBh.S3eEv.q0mSg.RZh8s.wxhnk.EcNvW.GccZQ.
|
||||
yO0Jb.n18hs.BLFx2.iigqf.AhsKS.LWqby.TUEmv.gmmhR.6DW3w.uLR0Y.
|
||||
QQBC8.YoQ63.g8m8i.iq3B-.SxwLn.jLbh3.l7cq3.eVQmV.5O2df.SXBkv.
|
||||
Y3LLb.denQq.GvR0R.P3Gh4.2iiq2.h-srW.o0ZZ-.HIrdj.npm5n.pnv07.
|
||||
vyT77.43WGP.Bciiq.zt1cI.7A4xB.zK9xm.-tV6x.ZdA6P.pheXQ.aSz4X.
|
||||
Zj2bS.C1UPx.~c1dS.xwF3b.6jZ-M.WI2eQ.e69Qw.DGFly.tTze-.GGbZU.
|
||||
qJ-m-.fD8yI.Adktz.oqTsF.F7ltA.6no6T.~fWJU.0gRsp.-P88x.a9I9b.
|
||||
Adkvz.ory8J.Ouhfu.H8c-U.2HLgE.Wi4xH.3AEGK.VjkS-.Z5hMx.UN5o~.
|
||||
Y~EWp.7LGox.IQxpt.cgONH.CEyKJ.jjTdM.GJ9HL.RloJZ.xuRtL.JZ7jg.
|
||||
ZZj6w.2AOoM.CENdS.xxegZ.RzTdh.i-1hZ.N1HPF.EqHU0.XzN6K.mBedG.
|
||||
uvBiL.HqpmY.Bl9z2.qzqA8.WzKqz.h~S1J.K2QHQ.Dy-CM.7RO0l.QksW3.
|
||||
mpFnx.fy-Pa.p7xhW.SboOd.fOBon.mCgSX.Z38Qe.dMHUC.79wje.wziG5.
|
||||
6Xtn7.ksEHO.xkBrO.e7yFe.vNaYx.FgDsI.BS9y8.AELs-.C9-DB.FAZI-.
|
||||
wKt2N.8qQhA.Apxm7.O5yIB.X51l9.Kduxm.SRA5N.UYi6I.MrySX.RZXrT.
|
||||
8UcY2.zUAfu.SOcUK.vZrDL.vBAHb.eOo~N.7J3sR.eJhSo.4~YE1.5k0h5.
|
||||
51RqS.b0jyR.RfhON.4Dt07.idahL.5isLK.eeBv3.znQxC.9LXkE.xKghP.
|
||||
Ia-R0.AgmB5.pGGIA.slCGu.CtR5q.NrzHh.1bscz.8CsWC.KH4it.LLrWm.
|
||||
UlRdr.lUGji.W76xr.kVAmO.6oAYS.7nXX~.kfeM2.TSS2m.JOCAb.sFFWg.
|
||||
4xH3C.MDKh4.FZso1.tXwUJ.Taq5K.8yS24.xHr4M.Kvu~E.HTpka.-Zg3f.
|
||||
KEXFS.qCKwh.l1KRN.c9H8A.HFcSw.rePCF.Iy93m.njkMZ.IEyiq.lFq3y.
|
||||
gRFzg.uL9tz.zP8du.Y1ZWP.PtQ6G.gzIt5.K8hNz.UAdpM.Q43L6.IMHx5.
|
||||
N8qPh.EfX8G.UC~68.S93ms.d18Vh.adkOx.GLkTI.khFcL.ZWG5G.Adoeh.
|
||||
hx~As.hci6I.Uq2pG.ykqHO.yUAdq.gQ7FD.4sOjn.IwGGw.UAdqo.Q4jVN.
|
||||
eJP8c.xQlm~.8nJ1y.gRF3g.oSPAM.fuqE0.M~23y.gRHyo.gngjF.ceM3n.
|
||||
V~uQy.93m-9.xa-3N.T80~v.GzR-g.HqBGA.mi4xH.3AMOL.mCjT5.Blqab.
|
||||
60ruw.HDV~k.Tj~fX.Swx8u.ZFOoi.m1GUF.Gs4-q.0kfxh.H8yjt.OCXGL.
|
||||
PYGTY.23LgI.Wl4x6.8bI3e.MXeVb.h6rL9.DXWyt.8wJ8W.HalWR.itqp3.
|
||||
pkrSC.8bQSM.HLV2J.G7sCj.QtGEi.AkSwI.A4P0J.gJ85j.MuMUY.nkT45.
|
||||
-rkqv.BFBFU.KGd98.qRs~A.iblOv.mVKWx.Z19cs.AxHc6.UIKJc.NIHW8.
|
||||
EnOEy.fygRG.29bbR.FBDVL.Ter6T.SBKat.MFBPE.AfuO9.kBHV~.QstE-.
|
||||
VaYNV.qpfhL.sFHj0.eFphG.U6Hw6.EsVox.7kpks.N6bRk.GMLY~.HWBVj.
|
||||
Snx6X.0GY2b.GhzmW.udfRF.jTgLC.uPWGL.fIwM6.16Ah4.NFZjz.Ftln7.
|
||||
KQ-k-.0SO8H.xrqcw.MXZG9.6BZsJ.zULJU.NPDy3.aewMa.3auiA.Ysei3.
|
||||
YQJGB.PlCAQ.S5YPU.uGEtI.wQrw1.cy8Sd.bFYuX.GGWZS.DSq1Y.O8ELq.
|
||||
cR6kA.dopig.RxB93.m6kAd.opigR.xB93m.6kAdo.pigRx.B93m6.kAdop.
|
||||
igRxB.93m6k.Adopi.gRxB9.3m6kA.doSsI.1Tves.7Fb5l.hneus.VDLsZ.
|
||||
~P3DD.D~CpI.BALPA.rxSTT.fuXa4.gP3Yv.sPKOY.KSMKP.balqk.xjbEH.
|
||||
idkbq.Elo0N.dHjkM.vEBiq.BC-Rb.IKMiB.JiaoS.x3mLy.Jr6P5.ToiS2.
|
||||
gAz4y.qNHiI.k7WIl.9EJGb.iJ2Tp.NQ5H5.VpSni.By-OX.TfvYs.plRic.
|
||||
rpPJD.7xkgk.h9BMw.001EY.XFJDs.CYKpn.1xoTd.HrCAK.tTtT0.6lOon.
|
||||
tQpCZ.jt5x5.t1A00.01UCO.x20ts.d003n.3g00s.RB8s0.A0002.8p0xY.
|
||||
20w82.5h9gD.c4000.0l9ny.s0000.0o8p0.0006g.0001i.h4x93.g0000.
|
||||
Eq2wR.7jB29
|
||||
0w89wg.GV4jA.l9000.00dPb.YzBT6.giO00.o100d.wZcqc.a9tg-.VTG0b.
|
||||
AUIvE.HBM3g.cK4SE.0aagi.l090p.I1P5g.Y-80r.y1YS9.1xE~Y.qgpFY.
|
||||
vKN1V.905y0.2UwvL.43TUw.uL406.0-31h.xwoJF.Ul454.ilk00.00Yps.
|
||||
BNumh.xpl9B.pS5Ji.i1BoC.ZAgg1.BsC5T.t6pLk.Thohn.gp000.0ov~P.
|
||||
7M000.0o840.00010.0001i.h4x93.g0000.Eq2wR.7jB29
|
||||
==
|
||||
::
|
||||
++ huff :: request by ship
|
||||
|
@ -438,7 +438,7 @@
|
||||
?. ?=([%$ ?(%da %ud %tas) *] a) ~
|
||||
[~ u=(^case a)]
|
||||
::
|
||||
++ hath (cook plex:voz (stag %clsg poor:voz)) :: hood path
|
||||
++ hath (sear plex:voz (stag %clsg poor:voz)) :: hood path
|
||||
++ have (sear tome ;~(pfix fas hath)) :: hood beam
|
||||
++ hood
|
||||
%+ ifix [gay gay]
|
||||
|
@ -8467,28 +8467,36 @@
|
||||
;~(plug (star low) (star hig))
|
||||
::
|
||||
++ plex
|
||||
|= gen=twig ~| [%plex gen] ^- path
|
||||
|= gen=twig ^- (unit path)
|
||||
?: ?=([%zpcb *] gen)
|
||||
$(gen q.gen)
|
||||
?> ?=([%clsg *] gen)
|
||||
(turn p.gen |=(a=twig ?>(?=(%dtzy -.a) q.a)))
|
||||
?. ?=([%clsg *] gen) ~
|
||||
%+ reel p.gen
|
||||
|= [a=twig b=_`(unit path)`[~ u=/]]
|
||||
?~ b ~
|
||||
?. ?=(%dtzy -.a) ~
|
||||
`[q.a u.b]
|
||||
::
|
||||
++ pray
|
||||
|= gen=twig ~| %pray ^- twig
|
||||
|= gen=twig ~| %pray ^- (unit twig)
|
||||
=+ rev=(plex gen)
|
||||
?: (~(has in was) rev)
|
||||
?~ rev ~
|
||||
:- ~
|
||||
?: (~(has in was) u.rev)
|
||||
~|(%pray-loop !!)
|
||||
=+ ruv=`path`(weld rev `path`[%hoon ~])
|
||||
=+ ruv=`path`(weld u.rev `path`[%hoon ~])
|
||||
=+ txt=(,@ta .^(%cx ruv))
|
||||
~| ruv
|
||||
%+ rash txt
|
||||
(ifix [gay gay] tall(was (~(put in was) rev), wer rev))
|
||||
(ifix [gay gay] tall(was (~(put in was) u.rev), wer u.rev))
|
||||
::
|
||||
++ prey
|
||||
|= gun=(list twig) ^- twig
|
||||
?~ gun [~ 1]
|
||||
?~ t.gun (pray i.gun)
|
||||
[%tsgr (pray i.gun) $(gun t.gun)]
|
||||
|= gun=(list twig) ^- (unit twig)
|
||||
?~ gun `[~ 1]
|
||||
=+ gup=(pray i.gun)
|
||||
?~ gup ~
|
||||
?~ t.gun gup
|
||||
(bind $(gun t.gun) |=(a=twig [%tsgr u.gup a]))
|
||||
::
|
||||
++ phax
|
||||
|= ruw=(list (list beer))
|
||||
@ -8910,7 +8918,7 @@
|
||||
[%dtkt %dtzz %$ %cx rev]
|
||||
;~(plug hill rood)
|
||||
==
|
||||
(cook prey (most ket rood))
|
||||
(sear prey (most ket rood))
|
||||
==
|
||||
==
|
||||
(stag %cnzz rope)
|
||||
@ -9202,7 +9210,7 @@
|
||||
:~ [':' ;~(pfix col (toad expz))]
|
||||
[',' (rune com %zpcm expb)]
|
||||
[';' (rune sem %zpsm expb)]
|
||||
['^' ;~(pfix ket (cook prey (toad exps)))]
|
||||
['^' ;~(pfix ket (sear prey (toad exps)))]
|
||||
['>' (rune gar %zpgr expa)]
|
||||
['=' (rune tis %zpts expa)]
|
||||
['?' (rune wut %zpwt hinh)]
|
||||
|
@ -1039,6 +1039,7 @@
|
||||
++ ze
|
||||
|_ [lim=@da dome rang]
|
||||
++ aeon-to-tako ~(got by hit)
|
||||
++ aeon-to-yaki (cork aeon-to-tako tako-to-yaki)
|
||||
++ make-yaki :: make yaki
|
||||
|= [p=(list tako) q=(map path lobe) t=@da]
|
||||
^- yaki
|
||||
@ -1109,17 +1110,16 @@
|
||||
((diff (blob-to-umph (lobe-to-blob u.leb))) zeq zoq)
|
||||
::
|
||||
++ lobes-at-path :: lobes-at-path:ze
|
||||
|= [oan=aeon pax=path] :: data at path
|
||||
|= [yon=aeon pax=path] :: data at path
|
||||
^- (map path lobe)
|
||||
?: =(0 oan) ~
|
||||
?: =(0 yon) ~
|
||||
%- mo
|
||||
%+ skim
|
||||
%. ~
|
||||
%~ tap by
|
||||
=< q
|
||||
%- tako-to-yaki
|
||||
%- aeon-to-tako
|
||||
oan
|
||||
%- aeon-to-yaki
|
||||
yon
|
||||
|= [p=path q=lobe]
|
||||
?| ?=(~ pax)
|
||||
?& !?=(~ p)
|
||||
@ -1137,8 +1137,7 @@
|
||||
?: =(0 let) [~ 0] :: avoid underflow
|
||||
?: %+ gte p.lok
|
||||
=< t
|
||||
%- tako-to-yaki
|
||||
%- aeon-to-tako
|
||||
%- aeon-to-yaki
|
||||
let
|
||||
[~ let]
|
||||
$(let (dec let))
|
||||
@ -1248,11 +1247,11 @@
|
||||
==
|
||||
::
|
||||
++ rewind :: rewind:ze
|
||||
|= oan=aeon :: rewind to aeon
|
||||
|= yon=aeon :: rewind to aeon
|
||||
^+ +>
|
||||
?: =(let oan) +>
|
||||
?: (gth oan let) !! :: don't have version
|
||||
+>(ank (checkout-ankh q:(tako-to-yaki (aeon-to-tako oan))), let oan)
|
||||
?: =(let yon) +>
|
||||
?: (gth yon let) !! :: don't have version
|
||||
+>(ank (checkout-ankh q:(aeon-to-yaki yon)), let yon)
|
||||
::
|
||||
::::
|
||||
++ update-lat :: update-lat:ze
|
||||
@ -1272,8 +1271,7 @@
|
||||
?: =(let 0) :: initial commit
|
||||
~ :: has nothing
|
||||
=< q
|
||||
%- tako-to-yaki
|
||||
%- aeon-to-tako
|
||||
%- aeon-to-yaki
|
||||
let
|
||||
%- |= bar=(map path blob) :: find unchanged
|
||||
=+ sar=(sa (turn lar |=([p=path *] p))) :: changed paths
|
||||
@ -1784,19 +1782,18 @@
|
||||
?^(r.mun ~ [~ let])
|
||||
?: ?=(%w p.mun)
|
||||
=+ ^= yak
|
||||
%- tako-to-yaki
|
||||
%- aeon-to-tako
|
||||
%- aeon-to-yaki
|
||||
let
|
||||
?^(r.mun ~ [~ [t.yak (forge-nori yak)]])
|
||||
::?> ?=(^ hit) ?^(r.mun ~ [~ i.hit]) :: what do?? need [@da nori]
|
||||
(query(ank ank:(descend-path:(zu ank) r.mun)) p.mun)
|
||||
::
|
||||
++ read-at-aeon :: read-at-aeon:ze
|
||||
|= [oan=aeon mun=mood] :: seek and read
|
||||
|= [yon=aeon mun=mood] :: seek and read
|
||||
^- (unit)
|
||||
?: &(?=(%w p.mun) !?=(%ud -.q.mun)) :: NB only for speed
|
||||
?^(r.mun ~ [~ oan])
|
||||
(read:(rewind oan) mun)
|
||||
?^(r.mun ~ [~ yon])
|
||||
(read:(rewind yon) mun)
|
||||
::
|
||||
++ equiv :: test paths
|
||||
|= [p=(map path lobe) q=(map path lobe)]
|
||||
@ -1824,12 +1821,12 @@
|
||||
%+ forge-yaki wen
|
||||
?: =(let 0) :: initial import
|
||||
[~ q.lem]
|
||||
[(some r:(tako-to-yaki (aeon-to-tako let))) q.lem]
|
||||
[(some r:(aeon-to-yaki let)) q.lem]
|
||||
=+ yak=-.yet
|
||||
=. lat +.yet :: merge objects
|
||||
?. ?| =(0 let)
|
||||
!=((lent p.yak) 1)
|
||||
!(equiv q.yak q:(tako-to-yaki (aeon-to-tako let)))
|
||||
!(equiv q.yak q:(aeon-to-yaki let))
|
||||
==
|
||||
+>.$ :: silently ignore
|
||||
=: let +(let)
|
||||
|
@ -1024,11 +1024,11 @@ which reads the requested data at the given revision.
|
||||
|
||||
```
|
||||
++ read-at-aeon :: read-at-aeon:ze
|
||||
|= [oan=aeon mun=mood] :: seek and read
|
||||
|= [yon=aeon mun=mood] :: seek and read
|
||||
^- (unit)
|
||||
?: &(?=(%w p.mun) !?=(%ud -.q.mun)) :: NB only for speed
|
||||
?^(r.mun ~ [~ oan])
|
||||
(read:(rewind oan) mun)
|
||||
?^(r.mun ~ [~ yon])
|
||||
(read:(rewind yon) mun)
|
||||
```
|
||||
|
||||
If we're requesting the revision number with a case other than by number, then
|
||||
@ -1038,11 +1038,11 @@ to get the requested information.
|
||||
|
||||
```
|
||||
++ rewind :: rewind:ze
|
||||
|= oan=aeon :: rewind to aeon
|
||||
|= yon=aeon :: rewind to aeon
|
||||
^+ +>
|
||||
?: =(let oan) +>
|
||||
?: (gth oan let) !! :: don't have version
|
||||
+>(ank (checkout-ankh q:(tako-to-yaki (aeon-to-tako oan))), let oan)
|
||||
?: =(let yon) +>
|
||||
?: (gth yon let) !! :: don't have version
|
||||
+>(ank (checkout-ankh q:(tako-to-yaki (aeon-to-tako yon))), let yon)
|
||||
```
|
||||
|
||||
If we're already at the requested version, we do nothing. If we're requesting
|
||||
@ -1490,9 +1490,9 @@ We call `++lobes-at-path:ze` to get the data at the particular path.
|
||||
|
||||
```
|
||||
++ lobes-at-path :: lobes-at-path:ze
|
||||
|= [oan=aeon pax=path] :: data at path
|
||||
|= [yon=aeon pax=path] :: data at path
|
||||
^- (map path lobe)
|
||||
?: =(0 oan) ~
|
||||
?: =(0 yon) ~
|
||||
%- mo
|
||||
%+ skim
|
||||
%. ~
|
||||
@ -1500,7 +1500,7 @@ We call `++lobes-at-path:ze` to get the data at the particular path.
|
||||
=< q
|
||||
%- tako-to-yaki
|
||||
%- aeon-to-tako
|
||||
oan
|
||||
yon
|
||||
|= [p=path q=lobe]
|
||||
?| ?=(~ pax)
|
||||
?& !?=(~ p)
|
||||
@ -1645,3 +1645,393 @@ Here, we just update the set of lobes we're given with the commits we're given
|
||||
and produce both sets.
|
||||
|
||||
This concludes our discussion of a local subscription.
|
||||
|
||||
Lifecycle of a Foreign Read or Subscription
|
||||
-------------------------------------------
|
||||
|
||||
Foreign reads and subscriptions are handled in much the same way as local ones.
|
||||
The interface is the same -- a vane or app sends a `%warp` kiss with the
|
||||
request. The difference is simply that the `sock` refers to the foreign ship.
|
||||
|
||||
Thus, we start in the same place -- in `++call`, handling `%warp`. However,
|
||||
since the two side of the `sock` are different, we follow a different path.
|
||||
|
||||
```
|
||||
=+ wex=(do now p.q.hic p.q.q.hic ruf)
|
||||
=+ ^= woo
|
||||
?~ q.q.q.hic
|
||||
abet:(ease:wex hen)
|
||||
abet:(eave:wex hen u.q.q.q.hic)
|
||||
[-.woo (posh q.p.q.hic p.q.q.hic +.woo ruf)]
|
||||
```
|
||||
|
||||
If we compare this to how the local case was handled, we see that it's not all
|
||||
that different. We use `++do` rather than `++un` and `++de` to set up the core
|
||||
for the foreign ship. This gives us a `++de` core, so we either cancel or
|
||||
begin the request by calling `++ease` or `++eave`, exactly as in the local
|
||||
case. In either case, we call `++abet:de` to resolve our various types of
|
||||
output into actual moves, as described in the local case. Finally, we call
|
||||
`++posh` to update our raft, putting the modified rung into the raft.
|
||||
|
||||
We'll first trace through `++do`.
|
||||
|
||||
```
|
||||
++ do
|
||||
|= [now=@da [who=ship him=ship] syd=@tas ruf=raft]
|
||||
=+ ^= rug ^- rung
|
||||
=+ rug=(~(get by hoy.ruf) him)
|
||||
?^(rug u.rug *rung)
|
||||
=+ ^= red ^- rede
|
||||
=+ yit=(~(get by rus.rug) syd)
|
||||
?^(yit u.yit `rede`[~2000.1.1 ~ [~ *rind] *dome])
|
||||
((de now ~ ~) [who him] syd red ran.ruf)
|
||||
```
|
||||
|
||||
If we already have a rung for this foreign ship, then we use that. Otherwise,
|
||||
we create a new blank one. If we already have a rede in this rung, then we use
|
||||
that, otherwise we create a blank one. An important point to note here is that
|
||||
we let `ref` in the rede be `[~ *rind]`. Recall, for domestic desks `ref` is
|
||||
null. We use this to distinguish between foreign and domestic desks in `++de`.
|
||||
|
||||
With this information, we create a `++de` core as usual.
|
||||
|
||||
Although we've already covered `++ease` and `++eave`, we'll go through them
|
||||
quickly again, highlighting the case of foreign request.
|
||||
|
||||
```
|
||||
++ ease :: release request
|
||||
|= hen=duct
|
||||
^+ +>
|
||||
=. qyx (~(del by qyx) hen)
|
||||
?~ ref +>
|
||||
|- ^+ +>+.$
|
||||
=+ nux=(~(get by fod.u.ref) hen)
|
||||
?~ nux +>+.$
|
||||
%= +>+.$
|
||||
say [[hen [(scot %ud u.nux) ~] for [u.nux syd ~]] say]
|
||||
fod.u.ref (~(del by fod.u.ref) hen)
|
||||
bom.u.ref (~(del by bom.u.ref) u.nux)
|
||||
==
|
||||
```
|
||||
|
||||
Here, we still remove the duct from our cult (we maintain a cult even for
|
||||
foreign desks), but we also need to tell the foreign desk to cancel our
|
||||
subscription. We do this by sending a request (by appending to `say`, which
|
||||
gets resolved in `++abet:de` to a `%want` kiss to ames) to the foreign ship to
|
||||
cancel the subscription. Since we don't anymore expect a response on this
|
||||
duct, we remove it from `fod` and `bom`, which are the maps between ducts,
|
||||
raves, and request sequence numbers. Basically, we remove every trace of the
|
||||
subscription from our request manager.
|
||||
|
||||
In the case of `++eave`, where we're creating a new request, everything is
|
||||
exactly identical to the case of the local request except `++duce`. We said
|
||||
that `++duce` simply puts the request into our cult. This is true for a
|
||||
domestic request, but distinctly untrue for foreign requests.
|
||||
|
||||
```
|
||||
++ duce :: produce request
|
||||
|= [hen=duct rov=rove]
|
||||
^+ +>
|
||||
=. qyx (~(put by qyx) hen rov)
|
||||
?~ ref +>.$
|
||||
|- ^+ +>+.$ :: XX why?
|
||||
=+ rav=(reve rov)
|
||||
=+ ^= vaw ^- rave
|
||||
?. ?=([%& %v *] rav) rav
|
||||
[%| [%ud let.dom] `case`q.p.rav r.p.rav]
|
||||
=+ inx=nix.u.ref
|
||||
%= +>+.$
|
||||
say [[hen [(scot %ud inx) ~] for [inx syd ~ vaw]] say]
|
||||
nix.u.ref +(nix.u.ref)
|
||||
bom.u.ref (~(put by bom.u.ref) inx [hen vaw])
|
||||
fod.u.ref (~(put by fod.u.ref) hen inx)
|
||||
==
|
||||
```
|
||||
|
||||
If we have a request manager (i.e. this is a foreign desk), then we do the
|
||||
approximate inverse of `++ease`. We create a rave out of the given request and
|
||||
send it off to the foreign desk by putting it in `say`. Note that the rave is
|
||||
created to request the information starting at the next revision number. Since
|
||||
this is a new request, we put it into `fod` and `bom` to associate the request
|
||||
with its duct and its sequence number. Since we're using another sequence
|
||||
number, we must increment `nix`, which represents the next available sequence
|
||||
number.
|
||||
|
||||
And that's really it for this side of the request. Requesting foreign
|
||||
information isn't that hard. Let's see what it looks like on the other side.
|
||||
When we get a request from another ship for information on our ship, that comes
|
||||
to us in the form of a `%wart` from ames.
|
||||
|
||||
We handle a `%wart` in `++call`, right next to where we handle the `%warp` case.
|
||||
|
||||
```
|
||||
%wart
|
||||
?> ?=(%re q.q.hic)
|
||||
=+ ryf=((hard riff) s.q.hic)
|
||||
:_ ..^$
|
||||
:~ :- hen
|
||||
:^ %pass [(scot %p p.p.q.hic) (scot %p q.p.q.hic) r.q.hic]
|
||||
%c
|
||||
[%warp [p.p.q.hic p.p.q.hic] ryf]
|
||||
==
|
||||
```
|
||||
|
||||
Every request we receive should be of type `riff`, so we coerce it into that
|
||||
type. We just convert this into a new `%warp` kiss that we pass to ourself.
|
||||
This gets handled like normal, as a local request. When the request produces
|
||||
a value, it does so like normal as a `%writ`, which is returned to `++take`
|
||||
along the path we just sent it on.
|
||||
|
||||
```
|
||||
%writ
|
||||
?> ?=([@ @ *] tea)
|
||||
=+ our=(need (slaw %p i.tea))
|
||||
=+ him=(need (slaw %p i.t.tea))
|
||||
:_ ..^$
|
||||
:~ :- hen
|
||||
[%pass ~ %a [%want [our him] [%r %re %c t.t.tea] p.+.q.hin]]
|
||||
==
|
||||
```
|
||||
|
||||
Since we encoded the ship we need to respond to in the path, we can just pass
|
||||
our `%want` back to ames, so that we tell the requesting ship about the new
|
||||
data.
|
||||
|
||||
This comes back to the original ship as a `%waft` from ames, which comes into
|
||||
`++take`, right next to where we handled `%writ`.
|
||||
|
||||
```
|
||||
%waft
|
||||
?> ?=([@ @ ~] tea)
|
||||
=+ syd=(need (slaw %tas i.tea))
|
||||
=+ inx=(need (slaw %ud i.t.tea))
|
||||
=+ ^= zat
|
||||
=< wake
|
||||
(knit:(do now p.+.q.hin syd ruf) [inx ((hard riot) q.+.q.hin)])
|
||||
=^ mos ruf
|
||||
=+ zot=abet.zat
|
||||
[-.zot (posh q.p.+.q.hin syd +.zot ruf)]
|
||||
[mos ..^$(ran.ruf ran.zat)] :: merge in new obj
|
||||
```
|
||||
|
||||
This gets the desk and sequence number from the path the request was sent over.
|
||||
This determines exactly which request is being responded to. We call
|
||||
`++knit:de` to apply the changes to our local desk, and we call `++wake` to
|
||||
update our subscribers. Then we call `++abet:de` and `++posh` as normal (like
|
||||
in `++eave`).
|
||||
|
||||
We'll examine `++knit` and `++wake`, in that order.
|
||||
|
||||
```
|
||||
++ knit :: external change
|
||||
|= [inx=@ud rot=riot]
|
||||
^+ +>
|
||||
?> ?=(^ ref)
|
||||
|- ^+ +>+.$
|
||||
=+ ruv=(~(get by bom.u.ref) inx)
|
||||
?~ ruv +>+.$
|
||||
=> ?. |(?=(~ rot) ?=(& -.q.u.ruv)) .
|
||||
%_ .
|
||||
bom.u.ref (~(del by bom.u.ref) inx)
|
||||
fod.u.ref (~(del by fod.u.ref) p.u.ruv)
|
||||
==
|
||||
?~ rot
|
||||
=+ rav=`rave`q.u.ruv
|
||||
%= +>+.$
|
||||
lim
|
||||
?.(&(?=(| -.rav) ?=(%da -.q.p.rav)) lim `@da`p.q.p.rav)
|
||||
::
|
||||
haw.u.ref
|
||||
?. ?=(& -.rav) haw.u.ref
|
||||
(~(put by haw.u.ref) p.rav ~)
|
||||
==
|
||||
?< ?=(%v p.p.u.rot)
|
||||
=. haw.u.ref
|
||||
(~(put by haw.u.ref) [p.p.u.rot q.p.u.rot q.u.rot] ~ r.u.rot)
|
||||
?. ?=(%w p.p.u.rot) +>+.$
|
||||
|- ^+ +>+.^$
|
||||
=+ nez=[%w [%ud let.dom] ~]
|
||||
=+ nex=(~(get by haw.u.ref) nez)
|
||||
?~ nex +>+.^$
|
||||
?~ u.nex +>+.^$ :: should never happen
|
||||
=. +>+.^$ =+ roo=(edis ((hard nako) u.u.nex))
|
||||
?>(?=(^ ref.roo) roo)
|
||||
%= $
|
||||
haw.u.ref (~(del by haw.u.ref) nez)
|
||||
==
|
||||
```
|
||||
|
||||
This is kind of a long gate, but don't worry, it's not bad at all.
|
||||
|
||||
First, we assert that we're not a domestic desk. That wouldn't make any sense
|
||||
at all.
|
||||
|
||||
Since we have the sequence number of the request, we can get the duct and rave
|
||||
from `bom` in our request manager. If we didn't actually request this data (or
|
||||
the request was canceled before we got it), then we do nothing.
|
||||
|
||||
Else, we remove the request from `bom` and `fod` unless this was a subscription
|
||||
request and we didn't receive a null riot (which would indicate the last
|
||||
message on the subscription).
|
||||
|
||||
Now, if we received a null riot, then if this was a subscription request by
|
||||
date, then we update `lim` in our request manager (representing the latest time
|
||||
at which we have complete information for this desk) to the date that was
|
||||
requested. If this was a single read request, then we put the result in our
|
||||
simple cache `haw` to make future requests faster. Then we're done.
|
||||
|
||||
If we received actual data, then we put it into our cache `haw`. Unless it's a
|
||||
`%w` request, we're done.
|
||||
|
||||
If it is a `%w` request, then we try to get the `%w` at our current head from
|
||||
the cache. In general, that should be the thing we just put in a moment ago,
|
||||
but that is not guaranteed. The most common case where this is different is
|
||||
when we receive desk updates out of order. At any rate, since we now have new
|
||||
information, we need to apply it to our local copy of the desk. We do so in
|
||||
`++edis`, and then we remove the stuff we just applied from the cache, since
|
||||
it's not really a true "single read", like what should really be in the cache.
|
||||
|
||||
```
|
||||
++ edis :: apply subscription
|
||||
|= nak=nako
|
||||
^+ +>
|
||||
%= +>
|
||||
hit.dom (~(uni by hit.dom) gar.nak)
|
||||
let.dom let.nak
|
||||
lat.ran %+ roll (~(tap in bar.nak) ~)
|
||||
=< .(yeb lat.ran)
|
||||
|= [sar=blob yeb=(map lobe blob)]
|
||||
=+ zax=(blob-to-lobe sar)
|
||||
%+ ~(put by yeb) zax sar
|
||||
hut.ran %+ roll (~(tap in lar.nak) ~)
|
||||
=< .(yeb hut.ran)
|
||||
|= [sar=yaki yeb=(map tako yaki)]
|
||||
%+ ~(put by yeb) r.sar sar
|
||||
==
|
||||
```
|
||||
|
||||
This shows, of course, exactly why nako is defined the way it is. To become
|
||||
completely up to date with the foreign desk, we need to merge `hit` with the
|
||||
foreign one so that we have all the revision numbers. We update `let` so that
|
||||
we know which revision is the head.
|
||||
|
||||
We merge the new blobs in `lat`, keying them by their hash, which we get from a
|
||||
call to `++blob-to-lobe`. Recall that the hash is stored in the actual blob
|
||||
itself. We do the same thing to the new yakis, putting them in `hut`, keyed by
|
||||
their hash.
|
||||
|
||||
Now, our local dome should be exactly the same as the foreign one.
|
||||
|
||||
This concludes our discussion of `++knit`. Now the changes have been applied to
|
||||
our local copy of the desk, and we just need to update our subscribers. We do
|
||||
so in `++wake:de`.
|
||||
|
||||
```
|
||||
++ wake :: update subscribers
|
||||
^+ .
|
||||
=+ xiq=(~(tap by qyx) ~)
|
||||
=| xaq=(list ,[p=duct q=rove])
|
||||
|- ^+ ..wake
|
||||
?~ xiq
|
||||
..wake(qyx (~(gas by *cult) xaq))
|
||||
?- -.q.i.xiq
|
||||
&
|
||||
=+ cas=?~(ref ~ (~(get by haw.u.ref) `mood`p.q.i.xiq))
|
||||
?^ cas
|
||||
%= $
|
||||
xiq t.xiq
|
||||
..wake ?~ u.cas (blub p.i.xiq)
|
||||
(blab p.i.xiq p.q.i.xiq u.u.cas)
|
||||
==
|
||||
=+ nao=(~(case-to-aeon ze lim dom ran) q.p.q.i.xiq)
|
||||
?~ nao $(xiq t.xiq, xaq [i.xiq xaq])
|
||||
$(xiq t.xiq, ..wake (balk p.i.xiq u.nao p.q.i.xiq))
|
||||
::
|
||||
|
|
||||
=+ mot=`moot`p.q.i.xiq
|
||||
=+ nab=(~(case-to-aeon ze lim dom ran) p.mot)
|
||||
?~ nab
|
||||
$(xiq t.xiq, xaq [i.xiq xaq])
|
||||
=+ huy=(~(case-to-aeon ze lim dom ran) q.mot)
|
||||
?~ huy
|
||||
=+ ptr=[%ud +(let.dom)]
|
||||
%= $
|
||||
xiq t.xiq
|
||||
xaq [[p.i.xiq [%| ptr q.mot r.mot s.mot]] xaq]
|
||||
..wake =+ ^= ear
|
||||
(~(lobes-at-path ze lim dom ran) let.dom r.p.q.i.xiq)
|
||||
?: =(s.p.q.i.xiq ear) ..wake
|
||||
=+ fud=(~(make-nako ze lim dom ran) u.nab let.dom)
|
||||
(bleb p.i.xiq let.dom fud)
|
||||
==
|
||||
%= $
|
||||
xiq t.xiq
|
||||
..wake =- (blub:- p.i.xiq)
|
||||
=+ ^= ear
|
||||
(~(lobes-at-path ze lim dom ran) u.huy r.p.q.i.xiq)
|
||||
?: =(s.p.q.i.xiq ear) (blub p.i.xiq)
|
||||
=+ fud=(~(make-nako ze lim dom ran) u.nab u.huy)
|
||||
(bleb p.i.xiq +(u.nab) fud)
|
||||
==
|
||||
==
|
||||
--
|
||||
```
|
||||
|
||||
This is even longer than `++knit`, but it's pretty similar to `++eave`. We loop
|
||||
through each of our subscribers `xiq`, processing each in turn. When we're done,
|
||||
we just put the remaining subscribers back in our subscriber list.
|
||||
|
||||
If the subscriber is a single read, then, if this is a foreign desk (note that
|
||||
`++wake` is called from other arms, and not only on foreign desks). Obviously,
|
||||
if we find an identical request there, then we can produce the result
|
||||
immediately. Referential transparency for the win. We produce the result with
|
||||
a call to `++blab`. If this is a foreign desk but the result is not in the
|
||||
cache, then we produce `++blub` (canceled subscription with no data) for
|
||||
reasons entirely opaque to me. Seriously, it seems like we should wait until
|
||||
we get an actual response to the request. If someone figures out why this is,
|
||||
let me know. At any rate, it seems to work.
|
||||
|
||||
If this is a domestic desk, then we check to see if the case exists yet. If
|
||||
it doesn't, then we simply move on to the next subscriber, consing this one
|
||||
onto `xaq` so that we can check again the next time around. If it does exist,
|
||||
then we call `++balk` to fulfill the request and produce it.
|
||||
|
||||
`++balk` is very simple, so we'll describe it here before we get to the
|
||||
subscription case.
|
||||
|
||||
```
|
||||
++ balk :: read and send
|
||||
|= [hen=duct yon=@ud mun=mood]
|
||||
^+ +>
|
||||
=+ vid=(~(read-at-aeon ze lim dom ran) yon mun)
|
||||
?~ vid (blub hen) (blab hen mun u.vid)
|
||||
```
|
||||
|
||||
We call `++read-at-aeon` on the given request and aeon. If you recall, this
|
||||
processes a `mood` at a particular aeon and produces the result, if there is
|
||||
one. If there is data at the requested location, then we produce it with
|
||||
`++blab`. Else, we call `++blub` to notify the subscriber that no data can
|
||||
ever come over this subscriptioin since it is now impossible for there to ever
|
||||
be data for the given request. Because referential transparency.
|
||||
|
||||
At any rate, back to `++wake`. If the given rave is a subscription request,
|
||||
then we proceed similarly to how we do in `++eave`. We first try to get the
|
||||
aeon referred to by the starting case. If it doesn't exist yet, then we can't
|
||||
do anything interesting with this subscription, so we move on to the next one.
|
||||
|
||||
Otherwise, we try to get the aeon referrred to by the ending case. If it
|
||||
doesn't exist yet, then we produce all the information we can. We call
|
||||
`++lobes-at-path` at the given aeon and path to see if the requested path has
|
||||
actually changed. If it hasn't, then we don't produce anything; else, we
|
||||
produce the correct nako by calling `++bleb` on the result of `++make-nako`, as
|
||||
in `++eave`. At any rate, we move on to the next subscription, putting back
|
||||
into our cult the current subscription with a new start case of the next aeon
|
||||
after the present.
|
||||
|
||||
If the aeon referred to by the ending case does exist, then we drop this
|
||||
subscriber from our cult and satisfy its request immediately. This is the same
|
||||
as before -- we check to see if the data at the path has actually changed,
|
||||
producing it if it has; else, we call `++blub` since no more data can be
|
||||
produced over this subscription.
|
||||
|
||||
This concludes our discussion of foreign requests.
|
||||
|
Loading…
Reference in New Issue
Block a user