mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-11-11 16:09:31 +03:00
update %clay doc
This commit is contained in:
parent
f84354bdcd
commit
afb776f077
@ -602,6 +602,28 @@ version reported (since a range of versions may be requested in a
|
||||
subscription). `r.p` is the desk. `q` is the path to the filesystem node.
|
||||
`r` is the data itself (in the format specified by `p.p`).
|
||||
|
||||
###`++nako`, subscription response data
|
||||
|
||||
```
|
||||
++ nako $: gar=(map ,@ud tako) :: new ids
|
||||
let=@ud :: next id
|
||||
lar=(set yaki) :: new commits
|
||||
bar=(set blob) :: new content
|
||||
== ::
|
||||
```
|
||||
|
||||
This is the data that is produced by a request for a range of revisions of a
|
||||
desk.
|
||||
|
||||
`gar` is a map of the revisions in the range to the hash of the commit
|
||||
at that revision. These hashes can be used with `hut:rang` to find the commit
|
||||
itself.
|
||||
|
||||
`let` is either the last revision number in the range or the most recent
|
||||
revision number, whichever is smaller.
|
||||
|
||||
`lar` is the set of new commits, and `bar` is the set of new content.
|
||||
|
||||
Interface
|
||||
---------
|
||||
|
||||
@ -720,8 +742,8 @@ another ship and, being a global filesystem, clay will happily produce it for
|
||||
you. That code pathway will be described in another section; here, we will
|
||||
restrict ourselves to examining the case of a read from a ship on our own pier.
|
||||
|
||||
The kiss can request either a single version of a file or a range of versions
|
||||
of a desk. We'll trace through both paths at once.
|
||||
The kiss can request either a single version of a file node or a range of
|
||||
versions of a desk. Here, we'll deal only with a request for a single version.
|
||||
|
||||
As in all vanes, a kiss enters clay via a call to `++call`. Scanning through
|
||||
the arm, we quickly see where `%warp` is handled.
|
||||
@ -1295,6 +1317,77 @@ If we're requesting the revision number of the desk and we're not requesting it
|
||||
by number, then we just return the current number of this desk. Note of course
|
||||
that this was really already handled in `++avid`.
|
||||
|
||||
If we're requesting a `%w` with a specific revision number, then we do
|
||||
something or other with the commit there. It's kind of weird, and it doesn't
|
||||
seem to work, so we'll ignore this case.
|
||||
|
||||
Otherwise, we descend into the ankh tree with `++deny:zu` to the given path,
|
||||
and then we handle specific request in `++amor`.
|
||||
|
||||
```
|
||||
++ deny :: descend recursively
|
||||
|= way=path
|
||||
^+ +>
|
||||
?~(way +> $(way t.way, +> (dent i.way)))
|
||||
```
|
||||
|
||||
This is simple recursion down into the ankh tree. `++dent` descends one level,
|
||||
so this will eventually get us down to the path we want.
|
||||
|
||||
```
|
||||
++ dent :: descend
|
||||
|= lol=@ta
|
||||
^+ +>
|
||||
=+ you=(~(get by r.ank) lol)
|
||||
+>.$(ram [lol ram], ank ?~(you [*cash ~ ~] u.you))
|
||||
```
|
||||
|
||||
`ram` is the path that we're at, so to descend one level we push the name of
|
||||
this level onto that path. We update the ankh with the correct one at that
|
||||
path if it exists; else we create a blank one.
|
||||
|
||||
Once we've decscended to the correct level, we need to actually deal with the
|
||||
request.
|
||||
|
||||
```
|
||||
++ amor :: amor:ze
|
||||
|= ren=?(%u %v %x %y %z) :: endpoint query
|
||||
^- (unit ,*)
|
||||
?- ren
|
||||
%u [~ `rang`+<+>.amor]
|
||||
%v [~ `dome`+<+<.amor]
|
||||
%x ?~(q.ank ~ [~ q.u.q.ank])
|
||||
%y [~ ache]
|
||||
%z [~ ank]
|
||||
==
|
||||
```
|
||||
|
||||
Now that everything's set up, it's really easy. If they're requesting the rang
|
||||
, dome, or ankh, we give it to them. If the contents of a file, we give it to
|
||||
them if it is in fact a file. If the `arch`, then we calculate it with `++ache`.
|
||||
|
||||
```
|
||||
++ ache :: ache:ze
|
||||
^- arch :: arch report
|
||||
:+ p.ank
|
||||
?~(q.ank ~ [~ p.u.q.ank])
|
||||
|- ^- (map ,@ta ,~)
|
||||
?~ r.ank ~
|
||||
[[p.n.r.ank ~] $(r.ank l.r.ank) $(r.ank r.r.ank)]
|
||||
```
|
||||
|
||||
This very simply strips out all the "real" data and returns just our own hash,
|
||||
the hash of the file contents (if we're a file), and a map of the names of our
|
||||
immediate children.
|
||||
|
||||
Lifecycle of a Local Subscription
|
||||
---------------------------------
|
||||
|
||||
A subscription to a range of revisions of a desk initially follows the same
|
||||
path that a single read does. In `++aver`, we checked the head of the given
|
||||
rave. If the head was `&`, then it was a single request, so we handled it
|
||||
above. If `|`, then we handle it with the following code.
|
||||
|
||||
```
|
||||
|
|
||||
=+ nab=(~(aeon ze lim dom ran) p.p.rav)
|
||||
@ -1315,4 +1408,143 @@ that this was really already handled in `++avid`.
|
||||
==
|
||||
```
|
||||
|
||||
(this is from `++eave`)
|
||||
Recall that `++aeon:ze` produces the revision number that a case corresponds
|
||||
to, if it corresponds to any. If it doesn't yet correspond to a revision, then
|
||||
it produces null.
|
||||
|
||||
Thus, we first check to see if we've even gotten to the beginning of the range
|
||||
of revisions requested. If not, then we assert that we haven't yet gotten to
|
||||
the end of the range either, because that would be really strange. If not,
|
||||
then we immediately call `++duce`, which, if you recall, for a local request,
|
||||
simply puts this duct and rave into our cult `qyx`, so that we know who to
|
||||
respond to when the revision does appear.
|
||||
|
||||
If we've already gotten to the first revision, then we can produce some content
|
||||
immediately. If we've also gotten to the final revision, and that revision is
|
||||
earlier than the start revision, then it's a bad request and we call `++blub`,
|
||||
which tells the subscriber that his subscription will not be satisfied.
|
||||
|
||||
Otherwise, we call `++gack`, which creates the `++nako` we need to produce. We
|
||||
call `++bleb` to actually produce the information. If we already have the last
|
||||
requested revision, then we also tell the subscriber with `++blub` that the
|
||||
subscription will receive no further updates.
|
||||
|
||||
If there will be more revisions, that we'll need to report, then we call
|
||||
`++duce`, adding the duct to our subscribers. We modify the rave to start at
|
||||
the next revision since we've already handled all the revisions up to the
|
||||
present.
|
||||
|
||||
We glossed over the calls to `++gack` and `++bleb`, so we'll get back to those
|
||||
right now. `++bleb` is simple, so we'll start with that.
|
||||
|
||||
```
|
||||
++ bleb :: ship sequence
|
||||
|= [hen=duct ins=@ud hip=nako]
|
||||
^+ +>
|
||||
(blab hen [%w [%ud ins] ~] hip)
|
||||
```
|
||||
|
||||
We're given a duct, the beginning revision number, and the nako that contains
|
||||
the updates since that revision. We use `++blab` to produce this result to
|
||||
the subscriber. The case is `%w` with a revision number of the beginning of the
|
||||
subscription, and the data is the nako itself.
|
||||
|
||||
Finally, we will describe `++gack:ze`.
|
||||
|
||||
```
|
||||
++ gack :: gack a through b
|
||||
|= [a=@ud b=@ud]
|
||||
^- [(map ,@ud tako) @ud (set yaki) (set blob)]
|
||||
:_ :- b
|
||||
%- hack
|
||||
%+ pack
|
||||
(~(get by hit) a) :: if a not found, a=0
|
||||
%- need (~(get by hit) b)
|
||||
^- (map ,@ud tako)
|
||||
%- mo %+ skim (~(tap by hit) ~)
|
||||
|= [p=@ud *]
|
||||
&((gth p a) (lte p b))
|
||||
```
|
||||
|
||||
|
||||
|
||||
```
|
||||
++ hack :: trivial
|
||||
|= [a=(set tako) b=(set lobe)]
|
||||
^- [(set yaki) (set blob)]
|
||||
:- %- sa %+ turn (~(tap by a) ~)
|
||||
|= tak=tako
|
||||
(need (~(get by hut) tak))
|
||||
%- sa %+ turn (~(tap by b) ~)
|
||||
|= lob=lobe
|
||||
(need (~(get by lat) lob))
|
||||
```
|
||||
|
||||
The type signature says everything you need to know about this. We take a set
|
||||
of hashes of commits and data and convert them into the actual commits and data
|
||||
in the most straightforward way possible.
|
||||
|
||||
```
|
||||
++ pack
|
||||
|= [a=(unit tako) b=tako] :: pack a through b
|
||||
^- [(set tako) (set lobe)]
|
||||
=+ ^= sar
|
||||
?~ a ~
|
||||
(zule r:(need (~(get by hut) u.a)))
|
||||
=+ yak=`yaki`(need (~(get by hut) b))
|
||||
%+ garf (garg ~ sar) :: get lobes
|
||||
|- ^- (set tako) :: walk onto sar
|
||||
?: (~(has in sar) r.yak)
|
||||
~
|
||||
=+ ber=`(set tako)`(~(put in `(set tako)`~) `tako`r.yak)
|
||||
%- ~(uni in ber)
|
||||
^- (set tako)
|
||||
%+ roll p.yak
|
||||
|= [yek=tako bar=(set tako)]
|
||||
^- (set tako)
|
||||
?: (~(has in bar) yek) :: save some time
|
||||
bar
|
||||
%- ~(uni in bar)
|
||||
^$(yak (need (~(get by hut) yek)))
|
||||
```
|
||||
|
||||
```
|
||||
++ zule :: reachable
|
||||
|= p=tako :: XX slow
|
||||
^- (set tako)
|
||||
=+ y=(~(got by hut) p)
|
||||
=+ t=(~(put in _(set tako)) p)
|
||||
%+ roll p.y
|
||||
|= [q=tako s=_t]
|
||||
?: (~(has in s) q) :: already done
|
||||
s :: hence skip
|
||||
(~(uni in s) ^$(p q)) :: otherwise traverse
|
||||
```
|
||||
|
||||
```
|
||||
++ garg :: object hash set
|
||||
|= [b=(set lobe) a=(set tako)] :: that aren't in b
|
||||
^- (set lobe)
|
||||
%+ roll (~(tap in a) ~)
|
||||
|= [tak=tako bar=(set lobe)]
|
||||
^- (set lobe)
|
||||
=+ yak=(need (~(get by hut) tak))
|
||||
%+ roll (~(tap by q.yak) ~)
|
||||
|= [[path lob=lobe] far=_bar]
|
||||
^- (set lobe)
|
||||
?~ (~(has in b) lob) :: don't need
|
||||
far
|
||||
=+ gar=(need (~(get by lat) lob))
|
||||
?- -.gar
|
||||
%direct (~(put in far) lob)
|
||||
%delta (~(put in $(lob q.gar)) lob)
|
||||
%indirect (~(put in $(lob s.gar)) lob)
|
||||
==
|
||||
```
|
||||
|
||||
```
|
||||
++ garf :: garg & repack
|
||||
|= [b=(set lobe) a=(set tako)]
|
||||
^- [(set tako) (set lobe)]
|
||||
[a (garg b a)]
|
||||
```
|
||||
|
Loading…
Reference in New Issue
Block a user