Merge pull request #6986 from urbit/develop

Release 411k-1
This commit is contained in:
Pyry Kovanen 2024-05-13 19:44:42 +03:00 committed by GitHub
commit 3f98200807
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
69 changed files with 4984 additions and 100645 deletions

View File

@ -102,7 +102,7 @@ in pkgs.stdenvNoCC.mkDerivation {
'';
checkPhase = ''
if egrep "((FAILED|CRASHED|Failed)|warn:)" $out >/dev/null; then
if egrep "((FAILED|CRASHED|Failed|\[0 %avow 0 %noun 1\])|warn:)" $out >/dev/null; then
exit 1
fi
'';

View File

@ -42,8 +42,8 @@
++ on-poke
|= [=mark =vase]
^- (quip card _this)
?> =(our src):bowl
?: ?=(%noun mark)
?> (team:title [our src]:bowl)
=/ code !<((unit @t) vase)
=/ msg=tape
?~ code
@ -55,6 +55,13 @@
"""
%- (slog leaf+msg ~)
[~ this(passcode code)]
?: ?=(%json mark)
=/ jon=json !<(json vase)
=, dejs:format
=/ cmd
((of clear-eyre-cache+(ot url+so ~) ~) jon)
?> ?=(%clear-eyre-cache -.cmd)
[[%pass /cmd %arvo %e %set-response +.cmd ~]~ this]
?. ?=(%handle-http-request mark)
(on-poke:def mark vase)
=+ !<([eyre-id=@ta =inbound-request:eyre] vase)
@ -315,6 +322,19 @@
:~ 'location'^s+(cat 3 (fall site '*') (spat path))
'action'^(render-action:v-eyre action)
==
::
:: /eyre/cache.json
::
[%eyre %cache ~]
%- some
:- %a
%+ turn (sort ~(tap by cache:v-eyre) aor)
|= [url=@t aeon=@ud val=(unit cache-entry:eyre)]
%- pairs
:~ 'url'^s+url
'aeon'^(numb aeon)
'val'^?~(val ~ (render-cache-entry:v-eyre u.val))
==
::
:: /eyre/connections.json
::
@ -566,7 +586,6 @@
%- pairs
:~ 'messages'^(numb (lent messages))
'packets'^(numb ~(wyt in packets))
'heeds'^(set-array heeds from-duct)
'keens'^(set-array ~(key by keens) path)
==
::
@ -630,7 +649,6 @@
:: }, ...],
:: closing: [bone, ..., bone],
:: corked: [bone, ..., bone],
:: heeds: [['/paths', ...] ...]
:: scries:
:: -> { =path
:: keen-state: {
@ -757,8 +775,6 @@
'closing'^(set-array closing numb)
::
'corked'^(set-array corked numb)
::
'heeds'^(set-array heeds from-duct)
::
'scries'^(scries ~(tap by keens))
==
@ -1038,6 +1054,9 @@
++ bindings
(scry ,(list [=binding =duct =action]) %e %bindings ~)
::
++ cache
(scry ,(map url=@t [aeon=@ud (unit cache-entry)]) %e %cache ~)
::
++ connections
(scry ,(map duct outstanding-connection) %e %connections ~)
::
@ -1065,6 +1084,27 @@
%gen :((cury cat 3) '+' (spat [desk path]:generator.action))
%app (cat 3 ':' app.action)
==
::
++ render-cache-entry
|= cache-entry
^- json
%- pairs:enjs:format
:~ 'auth'^b+auth
'payload'^(render-simple-payload simple-payload.body)
==
::
++ render-simple-payload
|= simple-payload:http
^- json
=, enjs:format
%- pairs
:~ 'status'^(numb status-code.response-header)
'data'^?~(data ~ (numb p.u.data))
::
:+ 'headers' %a
%+ turn headers.response-header
|=([k=@t v=@t] (pairs 'key'^s+k 'value'^s+v ~))
==
--
::
:: helpers

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,20 +1,16 @@
<!doctype html>
<html>
<head>
<title>Debug Dashboard</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<link rel="stylesheet" href="/~debug/css/index.css" />
<link rel="icon" type="image/png" href="/~launch/img/Favicon.png">
</head>
<body class="w-100 h-100">
<div id="root" class="w-100 h-100">
</div>
<script src="/~debug/js/channel.js"></script>
<script src="/~debug/js/session.js"></script>
<script src="/~debug/js/index.js"></script>
</body>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Debug Dashboard</title>
<style type="text/css" src="/src/index.css"></style>
<script type="module" crossorigin src="/~debug/index.js"></script>
<link rel="stylesheet" crossorigin href="/~debug/index.css">
</head>
<body>
<div id="root"></div>
<script src="/~debug/channel.js"></script>
<script src="/~debug/js/session.js"></script>
</body>
</html>

125
pkg/arvo/app/debug/index.js Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
import{errors as c,isChunkObject as y}from"./util.js";import"./index.js";let n=globalThis.File,p=globalThis.Blob;const m=o=>{n=o},g=o=>{p=o},{INVALID:z,GONE:s,MISMATCH:w,MOD_ERR:E,SYNTAX:l,DISALLOWED:O}=c;class D{constructor(e,i){this.fileHandle=e,this.file=i?e.file:new n([],e.file.name,e.file),this.size=i?e.file.size:0,this.position=0}async write(e){if(!this.fileHandle.file)throw new DOMException(...s);let i=this.file;if(y(e)){if(e.type==="write"){if(typeof e.position=="number"&&e.position>=0&&(this.position=e.position,this.size<e.position&&(this.file=new n([this.file,new ArrayBuffer(e.position-this.size)],this.file.name,this.file))),!("data"in e))throw new DOMException(...l("write requires a data argument"));e=e.data}else if(e.type==="seek")if(Number.isInteger(e.position)&&e.position>=0){if(this.size<e.position)throw new DOMException(...z);this.position=e.position;return}else throw new DOMException(...l("seek requires a position argument"));else if(e.type==="truncate")if(Number.isInteger(e.size)&&e.size>=0){i=e.size<this.size?new n([i.slice(0,e.size)],i.name,i):new n([i,new Uint8Array(e.size-this.size)],i.name,i),this.size=i.size,this.position>i.size&&(this.position=i.size),this.file=i;return}else throw new DOMException(...l("truncate requires a size argument"))}e=new p([e]);let t=this.file;const a=t.slice(0,this.position),d=t.slice(this.position+e.size);let r=this.position-a.size;r<0&&(r=0),t=new n([a,new Uint8Array(r),e,d],t.name),this.size=t.size,this.position+=e.size,this.file=t}async close(){if(!this.fileHandle.file)throw new DOMException(...s);this.fileHandle.file=this.file,this.file=this.position=this.size=null,this.fileHandle.onclose&&this.fileHandle.onclose(this.fileHandle)}}class f{constructor(e="",i=new n([],e),t=!0){this.kind="file",this.deleted=!1,this.file=i,this.name=e,this.writable=t}async getFile(){if(this.deleted||this.file===null)throw new DOMException(...s);return this.file}async createWritable(e){if(!this.writable)throw new DOMException(...O);if(this.deleted)throw new DOMException(...s);return new D(this,!!(e!=null&&e.keepExistingData))}async isSameEntry(e){return this===e}destroy(){this.deleted=!0,this.file=null}}class h{constructor(e,i=!0){this.kind="directory",this.deleted=!1,this._entries={},this.name=e,this.writable=i}async*entries(){if(this.deleted)throw new DOMException(...s);yield*Object.entries(this._entries)}async isSameEntry(e){return this===e}async getDirectoryHandle(e,i={}){if(this.deleted)throw new DOMException(...s);const t=this._entries[e];if(t){if(t instanceof f)throw new DOMException(...w);return t}else{if(i.create)return this._entries[e]=new h(e);throw new DOMException(...s)}}async getFileHandle(e,i={}){const t=this._entries[e];if(t){if(t instanceof f)return t;throw new DOMException(...w)}else{if(i.create)return this._entries[e]=new f(e);throw new DOMException(...s)}}async removeEntry(e,i={}){const t=this._entries[e];if(!t)throw new DOMException(...s);t.destroy(i.recursive),delete this._entries[e]}destroy(e){for(let i of Object.values(this._entries)){if(!e)throw new DOMException(...E);i.destroy(e)}this._entries={},this.deleted=!0}}const M=new h(""),u=()=>M;export{f as FileHandle,h as FolderHandle,u as default,g as setBlobImpl,m as setFileImpl};

View File

@ -0,0 +1,7 @@
function __vite__mapDeps(indexes) {
if (!__vite__mapDeps.viteFileDeps) {
__vite__mapDeps.viteFileDeps = ["memory.js","index.js","index.css"]
}
return indexes.map((i) => __vite__mapDeps.viteFileDeps[i])
}
import{_ as l}from"./index.js";const E={INVALID:["seeking position failed.","InvalidStateError"],GONE:["A requested file or directory could not be found at the time an operation was processed.","NotFoundError"],MISMATCH:["The path supplied exists, but was not an entry of requested type.","TypeMismatchError"],MOD_ERR:["The object can not be modified in this way.","InvalidModificationError"],SYNTAX:e=>[`Failed to execute 'write' on 'UnderlyingSinkBase': Invalid params passed. ${e}`,"SyntaxError"],ABORT:["The operation was aborted","AbortError"],SECURITY:["It was determined that certain files are unsafe for access within a Web application, or that too many calls are being made on file resources.","SecurityError"],DISALLOWED:["The request is not allowed by the user agent or the platform in the current context.","NotAllowedError"]},y=e=>typeof e=="object"&&typeof e.type<"u";async function v(e){var o,r,a;const{FolderHandle:t,FileHandle:u}=await l(()=>import("./memory.js"),__vite__mapDeps([0,1,2])),{FileSystemDirectoryHandle:m}=await l(()=>import("./index.js").then(n=>n.a),__vite__mapDeps([1,2])),p=(r=(o=e[0].webkitRelativePath)===null||o===void 0?void 0:o.split("/",1)[0])!==null&&r!==void 0?r:"",_=new t(p,!1);for(let n=0;n<e.length;n++){const i=e[n],d=!((a=i.webkitRelativePath)===null||a===void 0)&&a.length?i.webkitRelativePath.split("/"):["",i.name];d.shift();const f=d.pop(),w=d.reduce((c,s)=>(c._entries[s]||(c._entries[s]=new t(s,!1)),c._entries[s]),_);w._entries[f]=new u(i.name,i,!1)}return new m(_)}async function b(e){const{FileHandle:o}=await l(()=>import("./memory.js"),__vite__mapDeps([0,1,2])),{FileSystemFileHandle:r}=await l(()=>import("./index.js").then(t=>t.F),__vite__mapDeps([1,2]));return Array.from(e).map(t=>new r(new o(t.name,t,!1)))}export{E as errors,y as isChunkObject,v as makeDirHandleFromFileList,b as makeFileHandlesFromFileList};

View File

@ -168,7 +168,7 @@
::
;~ pfix tis
;~ pose
(parse-variable (jest %dir) ;~(pfix ace :(stag 0 %ex parse-rood)))
(parse-variable (cold %dir (jest 'dir ')) :(stag 0 %ex parse-rood))
(parse-variable sym ;~(pfix ace parse-source))
==
==

View File

@ -5,7 +5,6 @@
:: keep relevant mark conversions in cache for performance
::
/$ blit-to-json %blit %json
/$ json-to-blit %json %blit
/$ json-to-task %json %herm-task
::
=, jael

View File

@ -14,7 +14,7 @@
$: starting=(map yarn [=trying =vase])
running=(axal thread-form)
tid=(map tid yarn)
serving=(map tid [(unit @ta) =mark =desk])
serving=(map tid [(unit [rid=@ta take=?(%json %noun)]) =mark =desk])
scrying=(jug tid [=wire =ship =path])
==
::
@ -26,10 +26,20 @@
clean-slate-3
clean-slate-4
clean-slate-5
clean-slate-6
clean-slate
==
::
+$ clean-slate
$: %7
starting=(map yarn [=trying =vase])
running=(list yarn)
tid=(map tid yarn)
serving=(map tid [(unit [rid=@ta take=?(%json %noun)]) =mark =desk])
scrying=(jug tid [wire ship path])
==
::
+$ clean-slate-6
$: %6
starting=(map yarn [=trying =vase])
running=(list yarn)
@ -121,7 +131,8 @@
=. any (old-to-4 any)
=. any (old-to-5 any)
=. any (old-to-6 any)
?> ?=(%6 -.any)
=. any (old-to-7 any)
?> ?=(%7 -.any)
::
=. tid.state tid.any
=/ yarns=(list yarn)
@ -148,8 +159,8 @@
++ old-to-2
|= old=clean-slate-any
^- (quip card clean-slate-any)
?> ?=(?(%1 %2 %3 %4 %5 %6) -.old)
?: ?=(?(%2 %3 %4 %5 %6) -.old)
?> ?=(?(%1 %2 %3 %4 %5 %6 %7) -.old)
?: ?=(?(%2 %3 %4 %5 %6 %7) -.old)
`old
:- ~[bind-eyre:sc]
:* %2
@ -162,8 +173,8 @@
++ old-to-3
|= old=clean-slate-any
^- clean-slate-any
?> ?=(?(%2 %3 %4 %5 %6) -.old)
?: ?=(?(%3 %4 %5 %6) -.old)
?> ?=(?(%2 %3 %4 %5 %6 %7) -.old)
?: ?=(?(%3 %4 %5 %6 %7) -.old)
old
:* %3
starting.old
@ -175,8 +186,8 @@
++ old-to-4
|= old=clean-slate-any
^- clean-slate-any
?> ?=(?(%3 %4 %5 %6) -.old)
?: ?=(?(%4 %5 %6) -.old)
?> ?=(?(%3 %4 %5 %6 %7) -.old)
?: ?=(?(%4 %5 %6 %7) -.old)
old
:* %4
starting.old
@ -188,15 +199,15 @@
++ old-to-5
|= old=clean-slate-any
^- clean-slate-any
?> ?=(?(%4 %5 %6) -.old)
?: ?=(?(%5 %6) -.old) old
?> ?=(?(%4 %5 %6 %7) -.old)
?: ?=(?(%5 %6 %7) -.old) old
[%5 +.old(serving [serving.old ~])]
::
++ old-to-6
|= old=clean-slate-any
^- clean-slate
?> ?=(?(%5 %6) -.old)
?: ?=(%6 -.old) old
^- clean-slate-any
?> ?=(?(%5 %6 %7) -.old)
?: ?=(?(%6 %7) -.old) old
:- %6
%= +.old
scrying
@ -208,6 +219,16 @@
::
[/keen ship path]~
==
::
++ old-to-7
|= old=clean-slate-any
^- clean-slate-any
?> ?=(?(%6 %7) -.old)
?: ?=(%7 -.old) old
=- old(- %7, serving -)
%- ~(run by serving.old)
|= [request=(unit @ta) =mark =desk]
[(bind request (late %json)) mark desk]
--
::
++ on-poke
@ -309,15 +330,36 @@
=* 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)
=. 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)
?> ?=(^ body.request.inbound-request)
=/ body=json (need (de:json:html q.u.body.request.inbound-request))
=/ input=vase (slop !>(~) (tube !>(body)))
=/ test=$-(@t ?(%json %noun))
|= head=@t
=; type=(unit @t)
?:(=(`'application/x-urb-jam' type) %noun %json)
%+ bind
(get-header:http head header-list.request.inbound-request)
:(cork trip cass crip)
=/ give (test 'content-type')
=/ take (test 'accept')
::
=/ =tid (new-thread-id thread)
=. serving.state
(~(put by serving.state) tid [`[eyre-id take] output-mark desk])
::
=/ input=vase
%+ slop !>(~)
?- give
%json
=/ tube (convert-tube %json input-mark desk bowl)
=/ body=json (need (de:json:html q.u.body.request.inbound-request))
(tube !>(body))
::
%noun
=/ tube (convert-tube %noun input-mark desk bowl)
=/ body=noun (cue q.u.body.request.inbound-request)
(tube !>(body))
==
=/ boc bec
=/ =start-args:spider [~ `tid boc(q desk, r da+now.bowl) thread input]
(handle-start-thread start-args)
@ -550,18 +592,25 @@
=- (fall - `state)
%+ bind
(~(get by serving.state) tid)
|= [eyre-id=(unit @ta) output=mark =desk]
|= [request=(unit [rid=@ta take=?(%json %noun)]) output=mark =desk]
:_ state(serving (~(del by serving.state) tid))
?~ eyre-id
?~ request
~
%+ give-simple-payload:app:server u.eyre-id
%+ give-simple-payload:app:server rid.u.request
^- simple-payload:http
?. ?=(http-error:spider term)
%- (slog tang)
=/ tube (convert-tube %tang %json desk bowl)
:- [500 [['content-type' 'application/json'] ~]]
=- `(as-octs:mimes:html (en:json:html -))
o/(malt `(list [key=@t json])`[term+s/term tang+!<(json (tube !>(tang))) ~])
?- take.u.request
%json
=/ tube (convert-tube %tang %json desk bowl)
:- [500 [['content-type' 'application/json'] ~]]
=- `(as-octs:mimes:html (en:json:html -))
o/(malt `(list [key=@t json])`[term+s/term tang+!<(json (tube !>(tang))) ~])
::
%noun
:- [500 [['content-type' 'application/x-urb-jam'] ~]]
`(as-octs:mimes:html (jam [term tang]))
==
:_ ~ :_ ~
?- term
%bad-request 400
@ -588,13 +637,22 @@
=- (fall - `state)
%+ bind
(~(get by serving.state) tid)
|= [eyre-id=(unit @ta) output=mark =desk]
?~ eyre-id
|= [request=(unit [rid=@ta take=?(%json %noun)]) output=mark =desk]
?~ request
`state
=/ tube (convert-tube output %json desk bowl)
:_ state(serving (~(del by serving.state) tid))
%+ give-simple-payload:app:server u.eyre-id
(json-response:gen:server !<(json (tube vase)))
?- take.u.request
%json
=/ tube (convert-tube output %json desk bowl)
:_ state(serving (~(del by serving.state) tid))
%+ give-simple-payload:app:server rid.u.request
(json-response:gen:server !<(json (tube vase)))
::
%noun
:_ state(serving (~(del by serving.state) tid))
%+ give-simple-payload:app:server rid.u.request
:- [200 ['content-type' 'application/x-urb-jam']~]
`(as-octs:mimes:html (jam q.vase))
==
::
++ thread-done
|= [=yarn =vase silent=?]
@ -681,7 +739,7 @@
::
++ clean-state
!> ^- clean-slate
6+state(running (turn ~(tap of running.state) head))
7+state(running (turn ~(tap of running.state) head))
::
++ convert-tube
|= [from=mark to=mark =desk =bowl:gall]

View File

@ -2,6 +2,7 @@
!:
|%
+$ card card:agent:gall
+$ command $@(=test [=desk =test])
+$ test ?(%agents %marks %generators %threads)
+$ state
$: app=(set path)
@ -14,7 +15,6 @@
ted-ok=?
==
--
=, format
^- agent:gall
=| =state
|_ =bowl:gall
@ -28,9 +28,12 @@
|= [=mark =vase]
^- [(list card) _this]
?> (team:title [our src]:bowl)
=+ !<(cmd=command vase)
=? cmd ?=(@ cmd)
[q.byk.bowl test.cmd]
?> ?=(^ cmd)
|^
=+ !<(=test vase)
?- test
?- test.cmd
%marks test-marks
%agents test-agents
%generators test-generators
@ -54,7 +57,7 @@
|=(c=@tD `@tD`?:(=('/' c) '-' c))
=/ sing=card
:+ %pass /build/mar/[mak]
[%arvo %c %warp our.bowl q.byk.bowl ~ %sing %b da+now.bowl /[mak]]
[%arvo %c %warp our.bowl desk.cmd ~ %sing %b da+now.bowl /[mak]]
%_ $
paz t.paz
fex [sing fex]
@ -76,7 +79,7 @@
$(daz t.daz)
=/ sing=card
:+ %pass /build/app/[i.daz]
[%arvo %c %warp our.bowl q.byk.bowl ~ %sing %a da+now.bowl dap-pax]
[%arvo %c %warp our.bowl desk.cmd ~ %sing %a da+now.bowl dap-pax]
%_ $
daz t.daz
fex [sing fex]
@ -96,7 +99,7 @@
$(paz t.paz)
=/ sing=card
:+ %pass build+i.paz
[%arvo %c %warp our.bowl q.byk.bowl ~ %sing %a da+now.bowl i.paz]
[%arvo %c %warp our.bowl desk.cmd ~ %sing %a da+now.bowl i.paz]
%_ $
paz t.paz
fex [sing fex]
@ -116,13 +119,13 @@
$(paz t.paz)
=/ sing=card
:+ %pass build+i.paz
[%arvo %c %warp our.bowl q.byk.bowl ~ %sing %a da+now.bowl i.paz]
[%arvo %c %warp our.bowl desk.cmd ~ %sing %a da+now.bowl i.paz]
%_ $
paz t.paz
fex [sing fex]
ted.state (~(put in ted.state) i.paz)
==
++ now-beak %_(byk.bowl r [%da now.bowl])
++ now-beak [our.bowl desk.cmd da+now.bowl]
--
++ on-watch on-watch:def
++ on-leave on-leave:def

View File

@ -0,0 +1,161 @@
:: verb-logger: serializes verb-plus events to unix-side json
::
:: watches specified agents for "verb plus" events, buffers those, and
:: periodically (+write-interval) flushes them out to unix, under the
:: .urb/put/verb-logger/[agent] directory of the pier.
::
/+ verb, dbug, verb-json
::
|%
+$ state-0
$: %0
events=(jar dude:gall event-plus:verb)
==
::
+$ card card:agent:gall
::
++ write-interval ~h1
::
++ write-events
|= [our=ship =dude:gall events=(list event-plus:verb)]
^- (list card)
?: =(~ events) ~ ::NOTE tmi
=/ first=event-plus:verb
(rear events)
=/ pax=path
/verb-logger/[dude]/(crip (a-co:co (unm:chrono:userlib now.first)))/json
=/ vex=@
(en:json:html (events:enjs our dude events))
[%pass /write/[dude] %agent [our %hood] %poke %drum-put !>([pax vex])]~
::
++ ingest-event
|= $: our=ship
events=(jar dude:gall event-plus:verb)
[=dude:gall event=event-plus:verb]
==
^- (quip card _events)
?~ ves=(~(get ja events) dude)
:- ~
(~(put by events) dude [event ~])
?: .= (sub now.i.ves (mod now.i.ves write-interval))
(sub now.event (mod now.event write-interval))
:- ~
(~(put by events) dude [event ves])
:- (write-events our dude ves)
(~(put by events) dude [event ~])
::
++ enjs
=, enjs:format
|%
++ events
|= [our=@p =dude:gall events=(list event-plus:verb)] :: latest-first
=/ first=event-plus:verb (rear events)
%- pairs
:~ 'ship'^s+(scot %p our)
'dude'^s+dude
'from'^(time now.first)
::
:- 'events'
:- %a
%+ roll events ::NOTE we +roll to +turn & +flop simultaneously
|= [event=event-plus:verb out=(list json)]
[(event:enjs:verb-json event) out]
==
--
--
::
=| state-0
=* state -
::
%+ verb |
%- agent:dbug
|_ =bowl:gall
+* this .
::
++ on-init
^- (quip card _this)
[~ this]
::
++ on-save
!>(state)
::
++ on-load
|= ole=vase
^- (quip card _this)
[~ this(state !<(state-0 ole))]
::
++ on-poke
|= [=mark =vase]
^- (quip card _this)
?> =(%noun mark)
?+ q.vase !!
[%watch =dude:gall]
=* dude dude.q.vase
:_ this
[%pass /log/[dude] %agent [our.bowl dude] %watch /verb/events-plus]~
::
[%leave =dude:gall]
=* dude dude.q.vase
:- :- [%pass /log/[dude] %agent [our.bowl dude] %leave ~]
(write-events our.bowl dude (~(get ja events) dude))
this(events (~(del by events) dude))
::
[%flush =dude:gall]
|-
=* dude dude.q.vase
?. =(%$ dude)
:- (write-events our.bowl dude (~(get ja events) dude))
this(events (~(del by events) dude))
=| cards=(list card)
=/ dudes=(list dude:gall) ~(tap in ~(key by events))
|- ^- (quip card _this)
?~ dudes [cards this]
=^ caz this ^$(dude.q.vase i.dudes)
=. cards (weld cards caz)
$(dudes t.dudes)
==
::
++ on-agent
|= [=wire =sign:agent:gall]
^- (quip card _this)
~| wire
?+ wire !!
[%write @ ~]
=* dude i.t.wire
?> ?=(%poke-ack -.sign)
?~ p.sign [~ this]
%. [~ this]
%- %*(. slog pri 3)
[(cat 3 'verb-logger: lost export for %' dude) u.p.sign]
::
[%log @ ~]
=* dude i.t.wire
?- -.sign
%poke-ack !!
%kick =- [[-]~ this]
[%pass /log/[dude] %agent [our.bowl dude] %watch /verb/events-plus]
%watch-ack ?~ p.sign [~ this]
%. [~ this]
%- %*(. slog pri 2)
[(cat 3 'verb-logger: failed verb watch for %' dude) u.p.sign]
%fact ?> =(%verb-event-plus p.cage.sign)
=^ caz events
%- ingest-event
[our.bowl events dude !<(event-plus:verb q.cage.sign)]
[caz this]
==
==
::
++ on-fail
|= [=term =tang]
^- (quip card _this)
%. [~ this]
%- %*(. slog pri 3)
:_ tang
(cat 3 'verb-logger: dropping the ball: ' term)
::
++ on-watch |=(* !!)
++ on-leave |=(* !!)
++ on-arvo |=(* !!)
++ on-peek |=(* ~)
--

View File

@ -2,16 +2,36 @@
::
:::: /hoon/cp/hood/gen
::
:: XX clay discards the type, so %noun is used
:: copy by lobe should be used, if implemented
::
/? 310
:- %say
=, space:userlib
|= [^ [input=path output=path ~] ~]
|= [^ [input=path output=path ~] r=_|]
:- %kiln-info
?. =(-:(flop input) -:(flop output))
["Can't move to a different mark" ~]
=+ dir=.^(arch %cy input)
?~ fil.dir
~& "No such file:"
[<input> ~]
:- "copied"
`(foal output -:(flop input) [%atom %t ~] .^(* %cx input)) :: XX type
^- [mez=tape tor=(unit toro:clay)]
?. r
?. =(-:(flop input) -:(flop output))
["Can't move to a different mark" ~]
?~ =<(fil .^(arch %cy input))
~& "No such file:"
[<input> ~]
:- "copied"
`(foal output -:(flop input) [%noun .^(* %cx input)])
?~ in-beam=(de-beam input) ["bad input path" ~]
?~ =<(dir .^(arch %cy input)) ["input path isn't a directory" ~]
?~ out-beam=(de-beam output) ["bad output path" ~]
=/ in-beak=beak [p q r]:u.in-beam
=/ out-beak=beak [p q r]:u.out-beam
=/ =soba:clay
%+ murn .^((list path) %ct input)
|= pax=path
?: =(1 (sub (lent pax) (lent s.u.in-beam))) ~
=/ =cage
:- -:(flop pax)
[%noun .^(* %cx (en-beam in-beak pax))]
=/ =spur (weld s.u.out-beam (slag (lent s.u.in-beam) pax))
`[spur (feel (en-beam out-beak spur) cage)]
?~ soba ["nothing to copy" ~]
["copied" `[q.out-beak [%& soba]]]

View File

@ -24,6 +24,14 @@
?^ arg
mon.arg
(add our (lsh 5 (end 5 (shaz eny))))
=/ ryf=(unit rift)
.^((unit rift) %j /(scot %p p.bec)/ryft/(scot %da now)/(scot %p mon))
?^ ryf
%. ~
%- slog
:~ leaf+"can't create {(scow %p mon)}, it already exists."
'use |moon-breach and/or |moon-cycle-keys instead.'
==
=/ seg=ship (sein:title our now mon)
?. =(our seg)
%- %- slog :_ ~

View File

@ -2,6 +2,6 @@
:- %say
|= [[now=@da eny=@uvJ bec=beak] [syd=desk ~] verb=_&]
:* %tang
leaf+"Notice: +vat is deprecated. use +vats which now takes one or more desks as arguments. e.g. '+vats %base %garden'"
leaf+"Notice: +vat is deprecated. use +vats which now takes one or more desks as arguments. e.g. '+vats %base %landscape'"
(report-vat (report-prep p.bec now) p.bec now syd verb)
==

View File

@ -17,12 +17,4 @@
[filt=@tas verb=_|]
==
:- %tang ^- tang
?. &(=(~ deks) =(%$ filt))
(report-vats p.bec now deks filt verb)
%- zing
%+ turn
%+ sort
=/ sed .^((set desk) %cd /(scot %p p.bec)//(scot %da now))
(sort ~(tap in sed) |=([a=@ b=@] !(aor a b)))
|=([a=desk b=desk] ?|(=(a %kids) =(b %base)))
|=(syd=desk (report-vat (report-prep p.bec now) p.bec now syd verb))
(report-vats p.bec now deks filt verb)

View File

@ -1070,8 +1070,9 @@
++ wrd :: next or current word
|= a=(list @)
=| i=@ud
?~ a i
|- ^- @ud
?: |(?=(~ a) (alnm i.a)) i
?: |(?=(~ t.a) (alnm i.a)) i
$(i +(i), a t.a)
--
--

View File

@ -0,0 +1,78 @@
:: verb-json: conversions for verb events
::
/- verb
::
|%
++ enjs
=, enjs:format
|%
++ event
|= event-plus:verb
%- pairs
:~ 'act'^(numb act)
'now'^(time now) :: ms timestamp, lossy-ness is fine here
'src'^s+(scot %p src)
'sap'^s+(spat sap)
'kind'^s+-.cause
'deets'^(^cause cause)
'effects'^a+(turn effects effect)
==
::
++ cause
|= =cause:verb
^- json
?- -.cause
%on-init b+&
%on-load b+&
%on-poke (pairs 'mark'^s+mark.cause 'mug'^(mug mug.cause) ~)
%on-watch (path path.cause)
%on-leave (path path.cause)
%on-agent %- pairs
:~ 'wire'^(path wire.cause)
'sign'^s+-.sign.cause
::
:- 'deets'
?- -.sign.cause
%poke-ack b+ack.sign.cause
%watch-ack b+ack.sign.cause
%kick ~
%fact %- pairs
:~ 'mark'^s+mark.sign.cause
'mug'^(mug mug.sign.cause)
==
==
==
%on-arvo %- pairs
:~ 'wire'^(path wire.cause)
'vane'^s+vane.cause
'sign'^s+sign.cause
==
%on-fail s+term.cause
==
::
++ effect
|= effect:verb
^- json
%- pairs
:- 'kind'^s++<-
:_ ~
:- 'deets'
%- pairs
^- (list [@t json])
?- +<-
%poke :~ 'wire'^(path wire)
'gill'^(^gill gill)
'mark'^s+mark
'mug'^(^mug mug)
==
%watch ~['wire'^(^path wire) 'gill'^(^gill gill) 'path'^(^path path)]
%leave ~['wire'^(path wire) 'gill'^(^gill gill)]
%fact ~['paths'^a+(turn paths path) 'mark'^s+mark 'mug'^(^mug mug)]
%kick ~['paths'^a+(turn paths path)]
%arvo ~['wire'^(path wire) 'vane'^s+vane 'task'^s+task]
==
::
++ gill |=(=gill:gall `json`s+(rap 3 (scot %p p.gill) '/' q.gill ~))
++ mug |=(mug=@ux `json`s+(crip ((x-co:co 8) mug)))
--
--

View File

@ -0,0 +1,15 @@
/- verb
/+ verb-json
|_ =event-plus:verb
++ grad %noun
++ grab
|%
++ noun event-plus:verb
--
::
++ grow
|%
++ noun event-plus
++ json (event:enjs:verb-json event-plus)
--
--

View File

@ -2053,6 +2053,7 @@
+$ tang (list tank) :: bottom-first error
:: ::
+$ iota :: typed path segment
$+ iota
$~ [%n ~]
$@ @tas
$% [%ub @ub] [%uc @uc] [%ud @ud] [%ui @ui]
@ -2077,6 +2078,7 @@
:: flat-mid, open, close
::
+$ tank
$+ tank
$~ leaf/~
$@ cord
$% [%leaf p=tape]
@ -6392,6 +6394,7 @@
==
-- ::
+$ hoon :: hoon AST
$+ hoon
$~ [%zpzp ~] ::
$^ [p=hoon q=hoon] ::
$% ::
@ -6545,7 +6548,8 @@
[%know p=stud] :: global standard
[%made p=term q=(unit (list wing))] :: structure
== ::
+$ type $~ %noun ::
+$ type $+ type
$~ %noun ::
$@ $? %noun :: any nouns
%void :: no noun
== ::

View File

@ -765,8 +765,6 @@
::
:: %hear: packet from unix
:: %dear: lane from unix
:: %heed: track peer's responsiveness; gives %clog if slow
:: %jilt: stop tracking peer's responsiveness
:: %cork: request to delete message flow
:: %tame: request to delete route for ship
:: %kroc: request to delete specific message flows, from their bones
@ -797,8 +795,6 @@
$+ ames-task
$% [%hear =lane =blob]
[%dear =ship =lane]
[%heed =ship]
[%jilt =ship]
[%cork =ship]
[%tame =ship]
[%kroc bones=(list [ship bone])]
@ -828,6 +824,7 @@
:: Messaging Gifts
::
:: %boon: response message from remote ship
:: %noon: boon with duct for clog tracking
:: %clog: notify vane that %boon's to peer are backing up locally
:: %done: notify vane that peer (n)acked our message
:: %lost: notify vane that we crashed on %boon
@ -845,7 +842,7 @@
::
+$ gift
$% [%boon payload=*]
[%clog =ship]
[%noon id=* payload=*]
[%done error=(unit error)]
[%lost ~]
[%send =lane =blob]
@ -1012,13 +1009,11 @@
::
:: messages: pleas local vanes have asked us to send
:: packets: packets we've tried to send
:: heeds: local tracking requests; passed through into $peer-state
::
+$ alien-agenda
$+ alien-agenda
$: messages=(list [=duct =plea])
packets=(set =blob)
heeds=(set duct)
keens=(jug path duct)
chums=(jug path duct)
==
@ -1040,7 +1035,6 @@
:: information completes the packet+nack-trace, we remove the
:: entry and emit a nack to the local vane that asked us to send
:: the message.
:: heeds: listeners for %clog notifications
:: closing: bones closed on the sender side
:: corked: bones closed on both sender and receiver
::
@ -1058,7 +1052,6 @@
snd=(map bone message-pump-state)
rcv=(map bone message-sink-state)
nax=(set [=bone =message-num])
heeds=(set duct)
closing=(set bone)
corked=(set bone)
keens=(map path keen-state)
@ -2733,13 +2726,15 @@
|%
+$ gift :: outgoing result
$% [%boon payload=*] :: ames response
[%noon id=* payload=*]
[%done error=(unit error:ames)] :: ames message (n)ack
[%flub ~] :: not ready to handle plea
[%unto p=unto] ::
== ::
+$ task :: incoming request
$~ [%vega ~] ::
$% [%deal p=sack q=term r=deal] :: full transmission
$% [%clog id=*] :: clog notification
[%deal p=sack q=term r=deal] :: full transmission
[%sear =ship] :: clear pending queues
[%jolt =desk =dude] :: (re)start agent
[%idle =dude] :: suspend agent
@ -2816,6 +2811,7 @@
== ==
::
+$ bowl :: standard app state
$+ gall-agent-bowl ::
$: $: our=ship :: host
src=ship :: guest
dap=term :: agent
@ -2859,8 +2855,11 @@
=< form
|%
+$ step (quip card form)
+$ card (wind note gift)
+$ card
$+ gall-agent-card
(wind note gift)
+$ note
$+ gall-agent-note
$% [%agent [=ship name=term] =task]
[%arvo note-arvo]
[%pyre =tang]
@ -2876,6 +2875,7 @@
[%keen secret=? spar:ames]
==
+$ task
$+ gall-agent-task
$% [%watch =path]
[%watch-as =mark =path]
[%leave ~]
@ -2883,12 +2883,14 @@
[%poke-as =mark =cage]
==
+$ gift
$+ gall-agent-gift
$% [%fact paths=(list path) =cage]
[%kick paths=(list path) ship=(unit ship)]
[%watch-ack p=(unit tang)]
[%poke-ack p=(unit tang)]
==
+$ sign
$+ gall-agent-sign
$% [%poke-ack p=(unit tang)]
[%watch-ack p=(unit tang)]
[%fact =cage]
@ -3329,14 +3331,19 @@
|%
+$ card card:agent:gall
+$ input
$+ input
$% [%poke =cage]
[%sign =wire =sign-arvo]
[%agent =wire =sign:agent:gall]
[%watch =path]
==
+$ strand-input [=bowl in=(unit input)]
+$ error (pair term $+(tang tang))
+$ strand-input
$+ strand-input
[=bowl in=(unit input)]
+$ tid @tatid
+$ bowl
$+ strand-bowl
$: our=ship
src=ship
tid=tid
@ -3364,27 +3371,29 @@
::
++ strand-output-raw
|* a=mold
$+ strand-output-raw
$~ [~ %done *a]
$: cards=(list card)
$= next
$% [%wait ~]
[%skip ~]
[%cont self=(strand-form-raw a)]
[%fail err=(pair term tang)]
[%fail err=error]
[%done value=a]
==
==
::
++ strand-form-raw
|* a=mold
$+ strand-form-raw
$-(strand-input (strand-output-raw a))
::
:: Abort strand computation with error message
::
++ strand-fail
|= err=(pair term tang)
|= =error
|= strand-input
[~ %fail err]
[~ %fail error]
::
:: Asynchronous transcaction monad.
::
@ -3397,11 +3406,11 @@
++ strand
|* a=mold
|%
++ output (strand-output-raw a)
++ output $+(output (strand-output-raw a))
::
:: Type of an strand computation.
::
++ form (strand-form-raw a)
++ form $+(form (strand-form-raw a))
::
:: Monadic pure. Identity computation for bind.
::

View File

@ -76,13 +76,6 @@
:: Ames's perspective, the newly restarted peer is a new ship.
:: Ames's guarantees are not maintained across a breach.
::
:: A vane can pass Ames a %heed $task to request Ames track a peer's
:: responsiveness. If our %boon's to it start backing up locally,
:: Ames will give a %clog back to the requesting vane containing the
:: unresponsive peer's urbit address. This interaction does not use
:: ducts as unique keys. Stop tracking a peer by sending Ames a
:: %jilt $task.
::
:: Debug output can be adjusted using %sift and %spew $task's.
::
!:
@ -218,10 +211,7 @@
::
++ parse-bone-wire
|= =wire
^- %- unit
$% [%old her=ship =bone]
[%new her=ship =rift =bone]
==
^- (unit parsed-bone-wire)
?. ?| ?=([%bone @ @ @ ~] wire)
?=([%bone @ @ ~] wire)
==
@ -239,6 +229,11 @@
`@ud`(slav %ud i.t.t.wire)
`@ud`(slav %ud i.t.t.t.wire)
==
::
+$ parsed-bone-wire
$% [%old her=ship =bone]
[%new her=ship =rift =bone]
==
:: +make-pump-timer-wire: construct wire for |packet-pump timer
::
++ make-pump-timer-wire
@ -620,7 +615,7 @@
:: dead: dead flow consolidation timer and recork timer, if set
::
+$ ames-state
$+ ames-state-20
$+ ames-state-21
$: peers=(map ship ship-state)
=unix=duct
=life
@ -1280,6 +1275,17 @@
counter=@ud
==
::
+$ task-4-til-8
$+ task-4-til-8
$% [?(%heed %jilt) =ship] :: introduced in state %4, removed in %21
$<(?(%snub %kroc %deep %keen) task) :: tasks introduced later
==
+$ queued-event-4-til-8
$+ queued-event-4-til-8
$% [%call =duct wrapped-task=(hobo task-4-til-8)]
[%take =wire =duct =sign]
==
::
+$ queued-event-9-til-11
$+ queued-event-9-til-11
$% [%call =duct wrapped-task=(hobo task-9-til-11)]
@ -1290,6 +1296,7 @@
$+ task-9-til-11
$% [%kroc dry=?] :: introduced in state %10, modified in %17
[%snub ships=(list ship)] :: introduced in state %9, modified in %11
[?(%heed %jilt) =ship] :: introduced in state %4, removed in %21
$<(?(%snub %kroc %deep %keen) task) :: %deep/%keen introduced later
==
::
@ -1304,6 +1311,7 @@
$% [%kroc dry=?] :: introduced in state %10, modified in %17
[%keen spar] :: introduced in state %13, modified in %19
deep-task-14 :: introduced in state %14, modified in %19
[?(%heed %jilt) =ship] :: introduced in state %4, removed in %21
$<(?(%kroc %keen %deep) task)
==
::
@ -1326,6 +1334,7 @@
$+ task-16-and-18
$% [%keen spar] :: introduced in state %13, modified in %19
deep-task-14 :: introduced in state %14, modified in %19
[?(%heed %jilt) =ship] :: introduced in state %4, removed in %21
$<(?(%keen %deep) task)
==
::
@ -1336,7 +1345,7 @@
::
+$ ames-state-19
$+ ames-state-19
$: peers=(map ship ship-state)
$: peers=(map ship ship-state-20)
=unix=duct
=life
=rift
@ -1351,6 +1360,73 @@
::
=chain
==
::
+$ task-19-and-20
$+ task-19-and-20
$% [?(%heed %jilt) =ship] :: introduced in state %4, removed in %21
task
==
::
+$ queued-event-19-and-20
$+ queued-event-19-and-20
$% [%call =duct wrapped-task=(hobo task-19-and-20)]
[%take =wire =duct =sign]
==
::
+$ peer-state-20
$+ peer-state-20
$: $: =symmetric-key
=life
=rift
=public-key
sponsor=ship
==
route=(unit [direct=? =lane])
=qos
=ossuary
snd=(map bone message-pump-state)
rcv=(map bone message-sink-state)
nax=(set [=bone =message-num])
heeds=(set duct)
closing=(set bone)
corked=(set bone)
keens=(map path keen-state)
=chain
==
::
+$ alien-agenda-20
$+ alien-agenda-20
$: messages=(list [=duct =plea])
packets=(set =blob)
heeds=(set duct)
keens=(jug path duct)
chums=(jug path duct)
==
::
+$ ship-state-20
$+ ship-state-20
$% [%alien alien-agenda-20]
[%known peer-state-20]
==
::
+$ ames-state-20
$+ ames-state-20
$: peers=(map ship ship-state-20)
=unix=duct
=life
=rift
crypto-core=acru:ames
=bug
snub=[form=?(%allow %deny) ships=(set ship)]
cong=[msg=_5 mem=_100.000]
::
$= dead
$: flow=[%flow (unit dead-timer)]
cork=[%cork (unit dead-timer)]
==
::
=chain
==
:: $bug: debug printing configuration
::
:: veb: verbosity toggles
@ -1399,7 +1475,7 @@
$>(%flog task:dill)
==
$: %g
$>(%deal task:gall)
$>(?(%clog %deal) task:gall)
==
$: %j
$> $? %private-keys
@ -1433,7 +1509,7 @@
gift:jael
==
$: @tas
$>(?(%boon %done) gift:ames)
$>(?(%noon %boon %done) gift:ames)
== ==
::
:: $message-pump-task: job for |message-pump
@ -1504,7 +1580,8 @@
[%17 ames-state-17]
[%18 ames-state-17]
[%19 ames-state-19]
[%20 ^ames-state]
[%20 ames-state-20]
[%21 ^ames-state]
==
::
|= [now=@da eny=@ rof=roof]
@ -1627,52 +1704,52 @@
:: lifecycle arms; mostly pass-throughs to the contained adult ames
::
++ scry scry:adult-core
++ stay [%20 %larva queued-events ames-state.adult-gate]
++ stay [%21 %larva queued-events ames-state.adult-gate]
++ load
|= $= old
$% $: %4
$% $: %larva
events=(qeu queued-event)
events=(qeu queued-event-4-til-8)
state=ames-state-4
==
[%adult state=ames-state-4]
== ==
$: %5
$% $: %larva
events=(qeu queued-event)
events=(qeu queued-event-4-til-8)
state=ames-state-5
==
[%adult state=ames-state-5]
== ==
$: %6
$% $: %larva
events=(qeu queued-event)
events=(qeu queued-event-4-til-8)
state=ames-state-6
==
[%adult state=ames-state-6]
== ==
$: %7
$% $: %larva
events=(qeu queued-event)
events=(qeu queued-event-4-til-8)
state=ames-state-7
==
[%adult state=ames-state-7]
== ==
$: %8
$% $: %larva
events=(qeu queued-event)
events=(qeu queued-event-4-til-8)
state=ames-state-8
==
[%adult state=ames-state-8]
== ==
$: %9 :: %snub introduced
$: %9 :: %snub introduced
$% $: %larva
events=(qeu queued-event-9-til-11)
state=ames-state-9
==
[%adult state=ames-state-9]
== ==
$: %10 :: %kroc introduced
$: %10 :: %kroc introduced
$% $: %larva
events=(qeu queued-event-9-til-11)
state=ames-state-10
@ -1686,21 +1763,21 @@
==
[%adult state=ames-state-11]
== ==
$: %12 :: %snub modified
$: %12 :: %snub modified
$% $: %larva
events=(qeu queued-event-12-til-16)
state=ames-state-12
==
[%adult state=ames-state-12]
== ==
$: %13
$% $: %larva :: %keen introduced
$: %13 :: %keen introduced
$% $: %larva
events=(qeu queued-event-12-til-16)
state=ames-state-13
==
[%adult state=ames-state-13]
== ==
$: %14 :: %deep introduced
$: %14 :: %deep introduced
$% $: %larva
events=(qeu queued-event-12-til-16)
state=ames-state-14
@ -1721,7 +1798,7 @@
==
[%adult state=ames-state-16]
== ==
$: %17 :: %kroc modified
$: %17 :: %kroc modified
$% $: %larva
events=(qeu queued-event-17-and-18)
state=ames-state-17
@ -1735,14 +1812,21 @@
==
[%adult state=ames-state-18]
== ==
$: %19 :: %keen & %deep modified
$: %19 :: %keen & %deep modified
$% $: %larva
events=(qeu queued-event)
events=(qeu queued-event-19-and-20)
state=ames-state-19
==
[%adult state=ames-state-19]
== ==
$: %20 :: start informal %ping
$: %20 :: start informal %ping
$% $: %larva
events=(qeu queued-event-19-and-20)
state=ames-state-20
==
[%adult state=ames-state-20]
== ==
$: %21 :: remove %heed and %jilt
$% $: %larva
events=(qeu queued-event)
state=_ames-state.adult-gate
@ -1766,7 +1850,11 @@
[%5 %larva *]
~> %slog.0^leaf/"ames: larva %5 load"
=. cached-state `[%5 state.old]
=. queued-events events.old
=. queued-events %- event-20-to-21
%- event-17-and-18-to-20
%- event-12-til-16-to-17
%- event-9-til-11-to-12
events.old
larval-gate
::
[%6 %adult *]
@ -1777,7 +1865,11 @@
[%6 %larva *]
~> %slog.0^leaf/"ames: larva %6 load"
=. cached-state `[%6 state.old]
=. queued-events events.old
=. queued-events %- event-20-to-21
%- event-17-and-18-to-20
%- event-12-til-16-to-17
%- event-9-til-11-to-12
events.old
larval-gate
::
[%7 %adult *]
@ -1787,8 +1879,12 @@
::
[%7 %larva *]
~> %slog.0^leaf/"ames: larva %7 load"
=. queued-events events.old
=. cached-state `[%7 state.old]
=. queued-events %- event-20-to-21
%- event-17-and-18-to-20
%- event-12-til-16-to-17
%- event-9-til-11-to-12
events.old
larval-gate
::
[%8 %adult *]
@ -1799,7 +1895,11 @@
[%8 %larva *]
~> %slog.0^leaf/"ames: larva %8 load"
=. cached-state `[%8 state.old]
=. queued-events events.old
=. queued-events %- event-20-to-21
%- event-17-and-18-to-20
%- event-12-til-16-to-17
%- event-9-til-11-to-12
events.old
larval-gate
::
[%9 %adult *]
@ -1810,10 +1910,11 @@
[%9 %larva *]
~> %slog.0^leaf/"ames: larva %9 load"
=. cached-state `[%9 state.old]
=. queued-events %- event-17-and-18-to-last
%- event-12-til-16-to-17
%- event-9-til-11-to-12
events.old
=. queued-events %- event-20-to-21
%- event-17-and-18-to-20
%- event-12-til-16-to-17
%- event-9-til-11-to-12
events.old
larval-gate
::
[%10 %adult *]
@ -1824,10 +1925,11 @@
[%10 %larva *]
~> %slog.1^leaf/"ames: larva %10 load"
=. cached-state `[%10 state.old]
=. queued-events %- event-17-and-18-to-last
%- event-12-til-16-to-17
%- event-9-til-11-to-12
events.old
=. queued-events %- event-20-to-21
%- event-17-and-18-to-20
%- event-12-til-16-to-17
%- event-9-til-11-to-12
events.old
larval-gate
::
[%11 %adult *]
@ -1838,10 +1940,11 @@
[%11 %larva *]
~> %slog.1^leaf/"ames: larva %11 load"
=. cached-state `[%11 state.old]
=. queued-events %- event-17-and-18-to-last
%- event-12-til-16-to-17
%- event-9-til-11-to-12
events.old
=. queued-events %- event-20-to-21
%- event-17-and-18-to-20
%- event-12-til-16-to-17
%- event-9-til-11-to-12
events.old
larval-gate
::
[%12 %adult *]
@ -1852,9 +1955,10 @@
[%12 %larva *]
~> %slog.1^leaf/"ames: larva %12 load"
=. cached-state `[%12 state.old]
=. queued-events %- event-17-and-18-to-last
%- event-12-til-16-to-17
events.old
=. queued-events %- event-20-to-21
%- event-17-and-18-to-20
%- event-12-til-16-to-17
events.old
larval-gate
::
[%13 %adult *]
@ -1865,9 +1969,10 @@
[%13 %larva *]
~> %slog.1^leaf/"ames: larva %13 load"
=. cached-state `[%13 state.old]
=. queued-events %- event-17-and-18-to-last
%- event-12-til-16-to-17
events.old
=. queued-events %- event-20-to-21
%- event-17-and-18-to-20
%- event-12-til-16-to-17
events.old
larval-gate
::
[%14 %adult *]
@ -1878,9 +1983,10 @@
[%14 %larva *]
~> %slog.1^leaf/"ames: larva %14 load"
=. cached-state `[%14 state.old]
=. queued-events %- event-17-and-18-to-last
%- event-12-til-16-to-17
events.old
=. queued-events %- event-20-to-21
%- event-17-and-18-to-20
%- event-12-til-16-to-17
events.old
larval-gate
::
[%15 %adult *]
@ -1891,9 +1997,10 @@
[%15 %larva *]
~> %slog.1^leaf/"ames: larva %15 load"
=. cached-state `[%15 state.old]
=. queued-events %- event-17-and-18-to-last
%- event-12-til-16-to-17
events.old
=. queued-events %- event-20-to-21
%- event-17-and-18-to-20
%- event-12-til-16-to-17
events.old
larval-gate
::
[%16 %adult *]
@ -1904,9 +2011,10 @@
[%16 %larva *]
~> %slog.1^leaf/"ames: larva %16 load"
=. cached-state `[%16 state.old]
=. queued-events %- event-17-and-18-to-last
%- event-12-til-16-to-17
events.old
=. queued-events %- event-20-to-21
%- event-17-and-18-to-20
%- event-12-til-16-to-17
events.old
larval-gate
::
[%17 %adult *]
@ -1917,7 +2025,9 @@
[%17 %larva *]
~> %slog.1^leaf/"ames: larva %17 load"
=. cached-state `[%17 state.old]
=. queued-events (event-17-and-18-to-last events.old)
=. queued-events %- event-20-to-21
%- event-17-and-18-to-20
events.old
larval-gate
::
[%18 %adult *]
@ -1928,7 +2038,9 @@
[%18 %larva *]
~> %slog.1^leaf/"ames: larva %18 load"
=. cached-state `[%18 state.old]
=. queued-events (event-17-and-18-to-last events.old)
=. queued-events %- event-20-to-21
%- event-17-and-18-to-20
events.old
larval-gate
::
[%19 %adult *]
@ -1939,15 +2051,26 @@
[%19 %larva *]
~> %slog.1^leaf/"ames: larva %19 load"
=. cached-state `[%19 state.old]
=. queued-events events.old
=. queued-events (event-20-to-21 events.old)
larval-gate
::
[%20 %adult *] (load:adult-core %20 state.old)
[%20 %adult *]
=. cached-state `[%20 state.old]
~> %slog.0^leaf/"ames: larva %20 reload"
larval-gate
::
[%20 %larva *]
~> %slog.1^leaf/"ames: larva %20 load"
=. cached-state `[%20 state.old]
=. queued-events (event-20-to-21 events.old)
larval-gate
::
[%21 %adult *] (load:adult-core %21 state.old)
::
[%21 %larva *]
~> %slog.1^leaf/"ames: larva %21 load"
=. queued-events events.old
=. adult-gate (load:adult-core %20 state.old)
=. adult-gate (load:adult-core %21 state.old)
larval-gate
==
::
@ -1982,17 +2105,17 @@
[%kroc ~]
==
::
++ event-17-and-18-to-last
++ event-17-and-18-to-20
|= events=(qeu queued-event-17-and-18)
^- (qeu queued-event)
^- (qeu queued-event-19-and-20)
%- ~(rep in events)
|= [e=queued-event-17-and-18 q=(qeu queued-event)]
%- ~(put to q) ^- queued-event
|= [e=queued-event-17-and-18 q=(qeu queued-event-19-and-20)]
%- ~(put to q) ^- queued-event-19-and-20
?. ?=(%call -.e) e
=/ task=task-16-and-18 ((harden task-16-and-18) wrapped-task.e)
%= e
wrapped-task
^- ^task
^- task-19-and-20
?: ?=(%keen -.task)
[%keen ~ +.task]
?. ?=([%deep %nack *] task) task
@ -2005,6 +2128,17 @@
%naxplanation
[%deep %nack ship.task nack-bone.task ;;(message [hed msg])]
==
::
++ event-20-to-21
|= events=(qeu queued-event-19-and-20)
^- (qeu queued-event)
%- ~(rep in events)
|= [e=queued-event-19-and-20 q=(qeu queued-event)]
?. ?=(%call -.e) (~(put to q) e)
=/ task=task-19-and-20 ((harden task-19-and-20) wrapped-task.e)
?: ?=(?(%heed %jilt) -.task) q
(~(put to q) e(wrapped-task task))
::
--
:: +molt: re-evolve to adult-ames
::
@ -2075,7 +2209,9 @@
=+ ev-core=(ev [now eny rof] [/saxo]~ ames-state.adult-gate)
[unix-duct.+.u.cached-state %give %saxo get-sponsors:ev-core]
::
?> ?=(%20 -.u.cached-state)
=? u.cached-state ?=(%20 -.u.cached-state)
21+(state-20-to-21:load:adult-core +.u.cached-state)
?> ?=(%21 -.u.cached-state)
=. ames-state.adult-gate +.u.cached-state
[moz larval-core(cached-state ~)]
--
@ -2174,27 +2310,14 @@
~> %slog.0^leaf/"ames: dropping malformed wire: {(spud wire)}"
event-core
?> ?=([@ her=ship *] u.parsed)
=* her her.u.parsed
=/ peer-core (abed-got:pe her)
|^
?: ?& ?=([%new *] u.parsed)
(lth rift.u.parsed rift.peer-state.peer-core)
==
:: ignore events from an old rift
::
%- %^ ev-trace odd.veb her
|.("dropping old rift wire: {(spud wire)}")
=/ peer-core (abed-got:pe her.u.parsed)
?~ bon=(bone-ok u.parsed wire rift.peer-state.peer-core)
event-core
=/ =bone
?-(u.parsed [%new *] bone.u.parsed, [%old *] bone.u.parsed)
=? peer-core ?=([%old *] u.parsed)
%- %^ ev-trace odd.veb her
|.("parsing old wire: {(spud wire)}")
peer-core
|^
:: relay the vane ack to the foreign peer
::
=< abet
?~(error (send-ack bone) (send-nack bone u.error))
?~(error (send-ack u.bon) (send-nack u.bon u.error))
::
:: if processing succeded, send positive ack packet and exit
::
@ -2306,11 +2429,12 @@
%- (slog leaf+"ames: turning off dead flow consolidation" ~)
=. event-core
(emit:event-core duct.u.ded %pass wire.u.ded %b %rest date.u.ded)
=. flow.dead.ames-state.event-core [%flow ~]
(wake-dead-flows:event-core ~)
::
%- (slog leaf+"ames: switching to dead flow consolidation" ~)
=; cor=event-core
set-dead-flow-timer:(wake-dead-flows:cor ~)
set-dead-flow-timer:cor
%- ~(rep by peers.ames-state:event-core)
|= [[=ship =ship-state] core=_event-core]
^+ event-core
@ -2380,28 +2504,6 @@
|= =error
^+ event-core
(emit duct %pass /crud %d %flog %crud error)
:: +on-heed: handle request to track .ship's responsiveness
::
++ on-heed
|= =ship
^+ event-core
=/ ship-state (~(get by peers.ames-state) ship)
?: ?=([~ %known *] ship-state)
abet:on-heed:(abed-peer:pe ship +.u.ship-state)
%^ enqueue-alien-todo ship ship-state
|= todos=alien-agenda
todos(heeds (~(put in heeds.todos) duct))
:: +on-jilt: handle request to stop tracking .ship's responsiveness
::
++ on-jilt
|= =ship
^+ event-core
=/ ship-state (~(get by peers.ames-state) ship)
?: ?=([~ %known *] ship-state)
abet:on-jilt:(abed-peer:pe ship +.u.ship-state)
%^ enqueue-alien-todo ship ship-state
|= todos=alien-agenda
todos(heeds (~(del in heeds.todos) duct))
:: +on-dear: handle lane from unix
::
++ on-dear
@ -2633,6 +2735,40 @@
::
=< abet
(~(on-hear-shut-packet pe peer-state channel) [lane u.shut-packet dud])
::
++ bone-ok
|= [parsed=parsed-bone-wire =wire =rift]
^- (unit bone)
=* her her.parsed
::
?: ?& ?=([%new *] parsed)
(lth rift.parsed rift)
==
:: ignore events from an old rift
::
%- %^ ev-trace odd.veb her
|.("dropping old rift wire: {(spud wire)}")
~
=/ =bone
?-(parsed [%new *] bone.parsed, [%old *] bone.parsed)
=+ ?. ?=([%old *] parsed) ~
%- %^ ev-trace odd.veb her
|.("parsing old wire: {(spud wire)}")
~
`bone
::
++ on-take-noon
|= [=wire payload=* id=*]
^+ event-core
?~ parsed=(parse-bone-wire wire)
~> %slog.0^leaf/"ames: dropping malformed wire: {(spud wire)}"
event-core
?> ?=([@ her=ship *] u.parsed)
=/ peer-core (abed-got:pe her.u.parsed)
?~ bone=(bone-ok u.parsed wire rift.peer-state.peer-core)
event-core
::
abet:(check-clog:(on-memo:peer-core u.bone [%boon payload]) u.bone id)
:: +on-take-boon: receive request to give message to peer
::
++ on-take-boon
@ -2643,24 +2779,10 @@
event-core
::
?> ?=([@ her=ship *] u.parsed)
=* her her.u.parsed
=/ peer-core (abed-got:pe her)
::
?: ?& ?=([%new *] u.parsed)
(lth rift.u.parsed rift.peer-state.peer-core)
==
:: ignore events from an old rift
::
%- %^ ev-trace odd.veb her
|.("dropping old rift wire: {(spud wire)}")
=/ peer-core (abed-got:pe her.u.parsed)
?~ bone=(bone-ok u.parsed wire rift.peer-state.peer-core)
event-core
=/ =bone
?-(u.parsed [%new *] bone.u.parsed, [%old *] bone.u.parsed)
=? peer-core ?=([%old *] u.parsed)
%- %^ ev-trace odd.veb her
|.("parsing old wire: {(spud wire)}")
peer-core
abet:(on-memo:peer-core bone [%boon payload])
abet:(on-memo:peer-core u.bone [%boon payload])
:: +on-plea: handle request to send message
::
++ on-plea
@ -2854,7 +2976,7 @@
:: ames-state changes
::
++ wake-dead-flows
|= [error=(unit tang)]
|= error=(unit tang)
^+ event-core
%- ~(rep by peers.ames-state:event-core)
|= [[=ship =ship-state] core=_event-core]
@ -3171,12 +3293,6 @@
:: save current duct
::
=/ original-duct duct
:: apply heeds
::
=. event-core
%+ roll ~(tap in heeds.todos)
|= [=^duct core=_event-core]
(on-heed:core(duct duct) ship)
:: apply outgoing messages, reversing for FIFO order
::
=. event-core
@ -3589,11 +3705,7 @@
::
+| %tasks
::
++ on-heed
peer-core(heeds.peer-state (~(put in heeds.peer-state) duct))
::
++ on-jilt
peer-core(heeds.peer-state (~(del in heeds.peer-state) duct))
:: +update-qos: update and maybe print connection status
::
++ update-qos
@ -3610,12 +3722,7 @@
peer-core
:: print message
::
=. peer-core (pe-emit duct %pass /qos %d %flog %text u.text)
:: if peer has stopped responding, check if %boon's are backing up
::
?. ?=(?(%dead %unborn) -.qos.peer-state)
peer-core
check-clog
(pe-emit duct %pass /qos %d %flog %text u.text)
:: +on-hear-shut-packet: handle receipt of ack or message fragment
::
++ on-hear-shut-packet
@ -3654,6 +3761,15 @@
|= =bone
^+ peer-core
abet:(call:(abed:mi:peer-core bone) %flub ~)
::
++ check-clog
|= [=bone id=*]
^+ peer-core
=/ m=(unit message-pump-state) (~(get by snd.peer-state) bone)
?~ m peer-core
?: (gth ~(wyt in unsent-messages.u.m) msg.cong.ames-state)
(pe-emit [/ames]~ %pass /clog %g %clog id)
peer-core
:: +on-memo: handle request to send message
::
++ on-memo
@ -3668,13 +3784,7 @@
~> %slog.0^leaf/"ames: ignoring message on corked bone {<bone>}"
peer-core
::
=. peer-core abet:(call:(abed:mu bone) %memo message)
::
?: ?& ?=(%boon -.message)
(gte now (add ~s30 last-contact.qos.peer-state))
==
check-clog
peer-core
abet:(call:(abed:mu bone) %memo message)
:: +on-wake: handle timer expiration
::
++ on-wake
@ -3802,55 +3912,6 @@
recork-one
::
+| %implementation
:: +check-clog: notify clients if peer has stopped responding
::
++ check-clog
^+ peer-core
::
:: Only look at response bones. Request bones are unregulated,
:: since requests tend to be much smaller than responses.
::
=/ pumps=(list message-pump-state)
%+ murn ~(tap by snd.peer-state)
|= [=bone =message-pump-state]
?: =(0 (end 0 bone))
~
`u=message-pump-state
:: if clogged, notify client vane
::
|^ ?. &(nuf-messages nuf-memory) peer-core
%+ roll ~(tap in heeds.peer-state)
|=([d=^duct core=_peer-core] (pe-emit:core d %give %clog her))
:: +nuf-messages: are there enough messages to mark as clogged?
::
++ nuf-messages
=| num=@ud
|- ^- ?
?~ pumps |
=. num
;: add num
(sub [next current]:i.pumps)
~(wyt in unsent-messages.i.pumps)
==
?: (gte num msg.cong.ames-state)
&
$(pumps t.pumps)
:: +nuf-memory: is enough memory used to mark as clogged?
::
++ nuf-memory
=| mem=@ud
|- ^- ?
?~ pumps |
=. mem
%+ add
%- ~(rep in unsent-messages.i.pumps)
|=([m=message b=_mem] (add b (met 3 (jim m))))
?~ unsent-fragments.i.pumps 0
(met 3 fragment.i.unsent-fragments.i.pumps)
?: (gte mem mem.cong.ames-state)
&
$(pumps t.pumps)
--
:: +send-shut-packet: fire encrypted packet at rcvr and maybe sponsors
::
++ send-shut-packet
@ -5405,9 +5466,7 @@
%born on-born:event-core
%hear (on-hear:event-core [lane blob ~]:task)
%dear (on-dear:event-core +.task)
%heed (on-heed:event-core ship.task)
%init on-init:event-core
%jilt (on-jilt:event-core ship.task)
%prod (on-prod:event-core ships.task)
%sift (on-sift:event-core ships.task)
%snub (on-snub:event-core [form ships]:task)
@ -5437,7 +5496,7 @@
|= [=wire =duct dud=(unit goof) =sign]
^- [(list move) _ames-gate]
?^ dud
~|(%ames-take-dud (mean tang.u.dud))
~&(%ames-take-dud (mean tang.u.dud))
::
=/ event-core (ev [now eny rof] duct ames-state)
::
@ -5449,6 +5508,7 @@
?- sign
[@ %done *] (on-take-done:event-core wire error.sign)
[@ %boon *] (on-take-boon:event-core wire payload.sign)
[@ %noon *] (on-take-noon:event-core wire payload.sign id.sign)
::
[%ames %tune *] (on-tune:event-core wire [[ship path] roar]:sign)
::
@ -5464,15 +5524,15 @@
[moves ames-gate]
:: +stay: extract state before reload
::
++ stay [%20 %adult ames-state]
++ stay [%21 %adult ames-state]
:: +load: load in old state after reload
::
++ load
=< |= $= old-state
$% [%20 ^ames-state]
$% [%21 ^ames-state]
==
^+ ames-gate
?> ?=(%20 -.old-state)
?> ?=(%21 -.old-state)
ames-gate(ames-state +.old-state)
:: all state transitions are called from larval ames
::
@ -5714,7 +5774,7 @@
peers
%- ~(run by peers.old)
|= s=ship-state-17
^- ship-state
^- ship-state-20
?: ?=(%alien -.s)
%= s
keens [keens.s ~]
@ -5747,10 +5807,25 @@
::
++ state-19-to-20
|= old=ames-state-19
^- ^ames-state
^- ames-state-20
%= old
veb.bug [&1 &2 &3 &4 &5 &6 &7 &8 |8 %.n]:veb.bug.old
==
::
++ state-20-to-21
|= old=ames-state-20
^- ^ames-state
%= old
peers
%- ~(run by peers.old)
|= s=ship-state-20
^- ship-state
?: ?=(%alien -.s)
[%alien messages.s packets.s keens.s chums.s]
:* -.s -.+.s route.s qos.s ossuary.s snd.s rcv.s
nax.s closing.s corked.s keens.s chain.s
==
==
--
:: +scry: dereference namespace
::

View File

@ -729,11 +729,7 @@
::
%- (trace 1 |.("make cast {<a>} -> {<b>}"))
=^ old=vase nub (build-fit %mar a)
?: =/ ram (mule |.((slap old !,(*hoon grow))))
?: ?=(%| -.ram) %.n
=/ lab (mule |.((slob b p.p.ram)))
?: ?=(%| -.lab) %.n
p.lab
?: (has-arm %grow b old)
:: +grow core has .b arm; use that
::
%+ gain-leak cast+a^b
@ -749,8 +745,9 @@
:: try direct +grab
::
=^ new=vase nub (build-fit %mar b)
=/ arm=? (has-arm %grab a new)
=/ rab (mule |.((slap new tsgl/[limb/a limb/%grab])))
?: &(?=(%& -.rab) ?=(^ q.p.rab))
?: &(arm ?=(%& -.rab) ?=(^ q.p.rab))
%+ gain-leak cast+a^b
|= nob=state
%- (trace 4 |.("{<a>} -> {<b>}: +{(trip a)}:grab:{(trip b)}"))
@ -759,11 +756,11 @@
:: try +jump
::
=/ jum (mule |.((slap old tsgl/[limb/b limb/%jump])))
?: ?=(%& -.jum)
?: &((has-arm %jump a old) ?=(%& -.jum))
=/ via !<(mark p.jum)
%- (trace 4 |.("{<a>} -> {<b>}: via {<via>} per +jump:{(trip a)}"))
(compose-casts a via b)
?: ?=(%& -.rab)
?: &(arm ?=(%& -.rab))
=/ via !<(mark p.rab)
%- (trace 4 |.("{<a>} -> {<b>}: via {<via>} per +grab:{(trip b)}"))
(compose-casts a via b)
@ -787,6 +784,15 @@
%+ slap
(with-faces uno+uno dos+dos ~)
!,(*hoon |=(_+<.uno (dos (uno +<))))
::
++ has-arm
|= [arm=@tas =mark core=vase]
^- ?
=/ rib (mule |.((slap core [%wing ~[arm]])))
?: ?=(%| -.rib) %.n
=/ lab (mule |.((slob mark p.p.rib)))
?: ?=(%| -.lab) %.n
p.lab
:: +build-tube: produce a $tube mark conversion gate from .a to .b
::
++ build-tube
@ -4642,10 +4648,12 @@
$(desks t.desks)
=^ res den (aver:den ~ %x da+now /desk/bill)
=. ruf +:abet:den
?. ?=([~ ~ *] res)
=/ bill
?. ?=([~ ~ *] res) *bill
~|([%building-bill i.desks] !<(bill q.u.u.res))
?~ rid=(override bill ren.dom.den)
%- (trace 2 |.("{<i.desks>} has no dudes"))
$(desks t.desks)
=/ bill ~| [%building-bill i.desks] !<(bill q.u.u.res)
=/ rid (override bill ren.dom.den)
%- %+ trace 2 |.
"{<i.desks>} has bill {<bill>} and rein {<ren.dom.den>}, so {<rid>}"
=^ sats ..abet $(desks t.desks)
@ -4668,22 +4676,9 @@
:: +override: apply rein to bill
::
++ override
|= [duz=bill ren=(map dude:gall ?)]
^- bill
=. duz
%+ skip duz
|= =dude:gall
=(`| (~(get by ren) dude))
::
=/ dus (sy duz)
=. duz
%+ weld duz
%+ murn ~(tap by ren)
|= [=dude:gall on=?]
?: &(?=(%& on) !(~(has in dus) dude))
`u=dude
~
duz
|= [duz=bill ren=(map dude:gall ?)] ^- bill
=/ out=bill (skip duz ~(has by ren))
(~(rep by ren) |=([[d=dude:gall r=?] =_out] ?.(r out [d out])))
:: +apply-precedence: resolve conflicts between $bill's
::
:: policy is to crash if multiple desks are trying to run the same

View File

@ -798,14 +798,15 @@
=* headers header-list.request
:: for requests from localhost, respect the "forwarded" header
::
=/ [secure=? =^address]
=* same [secure address]
=/ [secure=? host=(unit @t) =^address]
=/ host=(unit @t) (get-header:http 'host' headers)
=* same [secure host address]
?. =([%ipv4 .127.0.0.1] address) same
?~ forwards=(forwarded-params headers) same
:- (fall (forwarded-secure u.forwards) secure)
:+ (fall (forwarded-secure u.forwards) secure)
(clap (forwarded-host u.forwards) host head)
(fall (forwarded-for u.forwards) address)
::
=/ host (get-header:http 'host' headers)
=/ [=action suburl=@t]
(get-action-for-binding host url.request)
::
@ -907,11 +908,12 @@
::
?: =('/_~_/' (end [3 5] url.request))
(handle-http-scry authenticated request)
:: handle requests to the cache
:: handle requests to the cache, if a non-empty entry exists
::
=/ entry (~(get by cache.state) url.request)
?: &(?=(^ entry) ?=(%'GET' method.request))
(handle-cache-req authenticated request val.u.entry)
=/ cached=(unit [aeon=@ud val=(unit cache-entry)])
(~(get by cache.state) url.request)
?: &(?=([~ @ ^] cached) ?=(%'GET' method.request))
(handle-cache-req authenticated request u.val.u.cached)
::
?- -.action
%gen
@ -1053,13 +1055,11 @@
:: +handle-cache-req: respond with cached value, 404 or 500
::
++ handle-cache-req
|= [authenticated=? =request:http entry=(unit cache-entry)]
|= [authenticated=? =request:http entry=cache-entry]
|^ ^- (quip move server-state)
?~ entry
(error-response 404 "cache entry for that binding was deleted")
?: &(auth.u.entry !authenticated)
?: &(auth.entry !authenticated)
(error-response 403 ~)
=* body body.u.entry
=* body body.entry
?- -.body
%payload
%- handle-response
@ -1306,11 +1306,23 @@
o(session-id session.fex)
:: store the hostname used for this login, later reuse it for eauth
::
=? endpoint.auth.state ?=(^ host)
=? endpoint.auth.state
:: avoid overwriting public domains with localhost
::
?& ?=(^ host)
?| ?=(~ auth.endpoint.auth.state)
!=('localhost' (fall (rush u.host host-sans-port) ''))
== ==
%- (trace 2 |.("eauth: storing endpoint at {(trip u.host)}"))
:+ user.endpoint.auth.state
=/ new-auth=(unit @t)
`(cat 3 ?:(secure 'https://' 'http://') u.host)
now
=, endpoint.auth.state
:+ user new-auth
:: only update the timestamp if the derived endpoint visibly changed.
:: that is, it's not hidden behind a user-provided hardcoded url,
:: and the new value is different from the old.)
::
?:(|(?=(^ user) =(new-auth auth)) time now)
::
=; out=[moves=(list move) server-state]
out(moves [give-session-tokens :(weld moz moves.fex moves.out)])
@ -3242,6 +3254,12 @@
%https `&
==
::
++ forwarded-host
|= forwards=(list (map @t @t))
^- (unit @t)
?. ?=(^ forwards) ~
(~(get by i.forwards) 'host')
::
++ parse-request-line
|= url=@t
^- [[ext=(unit @ta) site=(list @t)] args=(list [key=@t value=@t])]
@ -3507,6 +3525,8 @@
$(moves [mov moves], siz t.siz)
::
?: ?=(%eauth-host -.task)
?: =(user.endpoint.auth.server-state.ax host.task)
[~ http-server-gate]
=. user.endpoint.auth.server-state.ax host.task
=. time.endpoint.auth.server-state.ax now
[~ http-server-gate]
@ -4144,7 +4164,7 @@
?~ entry=(~(get by cache) u.url) ~
?. =(u.aeon aeon.u.entry) ~
?~ val=val.u.entry ~
?: &(auth.u.val !=([~ ~] lyc)) ~
?: &(auth.u.val !=([~ ~] lyc)) ~
``noun+!>(u.val)
:: private endpoints
?. ?=([~ ~] lyc) ~
@ -4153,6 +4173,7 @@
?+ tyl ~
[%$ %whey ~] =- ``mass+!>(`(list mass)`-)
:~ bindings+&+bindings.server-state.ax
cache+&+cache.server-state.ax
auth+&+auth.server-state.ax
connections+&+connections.server-state.ax
channels+&+channel-state.server-state.ax
@ -4189,6 +4210,7 @@
?. ?=(%$ ren) ~
?+ syd ~
%bindings ``noun+!>(bindings.server-state.ax)
%cache ``noun+!>(cache.server-state.ax)
%connections ``noun+!>(connections.server-state.ax)
%authentication-state ``noun+!>(auth.server-state.ax)
%channel-state ``noun+!>(channel-state.server-state.ax)

View File

@ -594,9 +594,6 @@
:: first contact; update state and subscribe to notifications
::
=. contacts.state (~(put in contacts.state) ship)
:: ask ames to track .ship's connectivity
::
=. moves [[system-duct.state %pass /sys/lag %a %heed ship] moves]
:: ask jael to track .ship's breaches
::
=/ =note-arvo [%j %public-keys (silt ship ~)]
@ -616,8 +613,6 @@
::
=. contacts.state (~(del in contacts.state) ship)
::
=. moves [[system-duct.state %pass /sys/lag %a %jilt ship] moves]
::
=/ =note-arvo [%j %nuke (silt ship ~)]
=. moves
[[system-duct.state %pass /sys/era note-arvo] moves]
@ -657,7 +652,6 @@
%lyv ..mo-core :: vestigial
%cor ..mo-core :: vestigial
%era (mo-handle-sys-era wire sign-arvo)
%lag (mo-handle-sys-lag wire sign-arvo)
%req (mo-handle-sys-req wire sign-arvo)
%way (mo-handle-sys-way wire sign-arvo)
==
@ -671,24 +665,20 @@
?. ?=(%breach -.public-keys-result.sign-arvo)
mo-core
(mo-breach /jael who.public-keys-result.sign-arvo)
:: +mo-handle-sys-lag: handle an ames %clog notification
:: +mo-handle-sys-clog: handle an ames %clog notification
::
++ mo-handle-sys-lag
|= [=wire =sign-arvo]
++ mo-handle-sys-clog
|= [=duct agent-name=term]
^+ mo-core
=/ yoke (~(get by yokes.state) agent-name)
?~ yoke
mo-core
=? mo-core ?=(%live -.u.yoke)
=/ app (ap-abed:ap agent-name [~ our /ames])
ap-abet:(ap-clog:app duct)
::
?> ?=([%lag ~] wire)
?> ?=([%ames %clog *] sign-arvo)
::
=/ agents=(list [=dude =yoke]) ~(tap by yokes.state)
|- ^+ mo-core
?~ agents mo-core
::
=? mo-core ?=(%live -.yoke.i.agents)
=/ app (ap-abed:ap dude.i.agents [~ our /ames])
ap-abet:(ap-clog:app ship.sign-arvo)
::
$(agents t.agents)
mo-core
::
:: +mo-handle-sys-req: TODO description
::
:: TODO: what should we do if the remote nacks our %pull?
@ -699,7 +689,6 @@
?> ?=([%req @ @ ~] wire)
=/ him (slav %p i.t.wire)
=/ dap i.t.t.wire
::
?> ?=([?(%gall %behn) %unto *] sign-arvo)
=/ =unto +>.sign-arvo
::
@ -713,7 +702,7 @@
::
%fact
=+ [mark noun]=[p q.q]:cage.unto
(mo-give %boon %d mark noun)
(mo-give %noon [dap [/gall/sys/req/[i.t.wire]/[dap] hen]] %d mark noun)
::
%kick
(mo-give %boon %x ~)
@ -734,6 +723,7 @@
=/ foreign-agent i.t.t.wire
::
?+ sign-arvo !!
::
[%ames %done *]
=/ err=(unit tang)
?~ error=error.sign-arvo
@ -754,13 +744,17 @@
~| [full-wire=full-wire hen=hen stand=stand]
=^ rr stand ~(get to stand)
:- rr
?: =(~ stand)
:: outstanding leaves are only deleted when acked
::
?: &(?=(^ err) ?=(%leave rr))
outstanding.state
?. =(~ stand)
(~(put by outstanding.state) [full-wire hen] stand)
:: outstanding leaves are only deleted when acked;
:: a nacked %leave is flagged with a %missing request
:: we add to the outstanding queue that is only checked
:: in the nacked-leaves timer to skip dead-flow %leave(s)
::
?. &(?=(^ err) ?=(%leave rr))
(~(del by outstanding.state) [full-wire hen])
(~(put by outstanding.state) [full-wire hen] stand)
%- ~(put by outstanding.state)
[[full-wire hen] (~(gas to stand) ~[%leave %missing])]
:: non-null case of wire is old, remove on next breach after
:: 2019/12
::
@ -1147,10 +1141,8 @@
++ mo-handle-ames-request
|= [=ship agent-name=term =ames-request]
^+ mo-core
:: %u/%leave gets automatically acked
::
=. mo-core (mo-track-ship ship)
=? mo-core ?=(%u -.ames-request) (mo-give %done ~)
::
=/ yok=(unit yoke) (~(get by yokes.state) agent-name)
?~ yok
@ -1160,6 +1152,10 @@
?: ?=(%.n -.agent.u.yok)
(mo-give %flub ~)
::
:: %u/%leave gets automatically acked
::
=? mo-core ?=(%u -.ames-request)
(mo-give %done ~)
=/ =wire /sys/req/(scot %p ship)/[agent-name]
::
=/ =deal
@ -1647,17 +1643,11 @@
:: TODO: %drip local app notification for error isolation
::
++ ap-clog
|= =ship
|= =duct
^+ ap-core
::
=/ in=(list [=duct =^ship =path]) ~(tap by bitt.yoke)
|- ^+ ap-core
?~ in ap-core
::
=? ap-core =(ship ship.i.in)
=/ core ap-kill-up(agent-duct duct.i.in)
core(agent-duct agent-duct)
$(in t.in)
=/ core ap-kill-up(agent-duct duct)
core(agent-duct agent-duct)
:: +ap-agent-core: agent core with current bowl and state
::
++ ap-agent-core
@ -2363,6 +2353,10 @@
::
=/ mo-core (mo-abed:mo duct)
?- -.task
%clog
=+ ;;([dap=@tas =^duct] id.task)
mo-abet:(mo-handle-sys-clog:mo-core duct dap)
::
%deal
=/ [=sack =term =deal] [p q r]:task
?. =(q.sack our)
@ -2456,6 +2450,7 @@
blocked=(map term (qeu blocked-move-13))
=bug
==
::
+$ blocked-move-13 [=duct routes=routes-13 move=(each deal unto)]
+$ routes-13
$: disclosing=(unit (set ship))
@ -2854,6 +2849,7 @@
~
``case/!>(ud/key.u.las)
::
=? path =(/whey path) /1/whey
?: &(?=(%x care) ?=([%'1' *] path))
=> .(path t.path)
?. =(p.bem our) ~
@ -2998,14 +2994,29 @@
%- ~(rep by outstanding.state)
|= [[[=^wire =^duct] stand=(qeu remote-request)] core=_mo-core:mo]
?: =(~ stand) core
=^ rr stand ~(get to stand)
=^ rr stand ~(get to stand)
:: sanity check in the outstanding queue:
:: if there's a %leave, that should be the only request
:: if there's a %leave that was nacked, there should be a %missing request
:: otherwise %leave is the only request in the queue, and we haven't heard
:: anc %ack or a %nack, so %ames is still trying to send it.
::
~? >>> &(?=(%leave rr) =(^ stand))
"outstanding queue not empty [{<wire>} {<duct>} {<stand>}]"
=? core &(?=(%leave rr) =(~ stand))
(mo-handle-nacked-leaves:(mo-abed:core duct) wire)
~? >>> ?& ?=(%leave rr)
=(^ stand)
=^(rr stand ~(get to stand) !=(%missing rr))
==
"extraneous request outstanding [{<wire>} {<duct>} {<stand>} {<rr>}]"
=? core ?& ?=(%leave rr)
=(^ stand)
=^(rr stand ~(get to stand) &(=(%missing rr) =(~ stand)))
==
=+ core=(mo-handle-nacked-leaves:(mo-abed:core duct) wire)
:: make sure that only the %leave remains in the queue
::
%_ core
outstanding.state
%+ ~(put by outstanding.state) [wire duct]
(~(put to *(qeu remote-request)) %leave)
==
core
::
~| [%gall-take-failed wire]

View File

@ -670,7 +670,9 @@
$(yez t.yez)
::
:: We want to notify Ames, then Clay, then Gall. This happens to
:: be alphabetical, but this is mostly a coincidence.
:: be alphabetical, but this is mostly a coincidence. We also have
:: to notify Gall the vane before we notify any Gall agents, so we
:: can kiss the coincidence goodbye.
::
++ sorter
|= [a=duct b=duct]
@ -678,6 +680,8 @@
|
?. ?=([[@ *] *] b)
&
?: &(?=([[%gall *] *] a) ?=([[%gall *] *] b))
?=([%gall %sys *] i.a)
(lth (end 3 i.i.a) (end 3 i.i.b))
--
::

View File

@ -17,14 +17,14 @@
::
++ run-test
|= [pax=path test=test-func]
^- [ok=? output=tang result=tang]
^- [ok=? =tang]
=+ name=(spud pax)
=+ run=(mule test)
?- -.run
%| |+[p.run [leaf+"CRASHED {name}" ~]]
%| |+(welp p.run leaf+"CRASHED {name}" ~)
%& ?: =(~ p.run)
&+[p.run [leaf+"OK {name}" ~]]
|+[p.run [leaf+"FAILED {name}" ~]]
&+[leaf+"OK {name}"]~
|+(flop `tang`[leaf+"FAILED {name}" p.run])
==
:: +resolve-test-paths: add test names to file paths to form full identifiers
::
@ -103,10 +103,10 @@
::
?~ q.arg
~[/(scot %p our.bowl)/[q.byk.bowl]/(scot %da now.bowl)/tests]
:: else cast path to ~[path] if needed
::
?~ +.q.arg
~[/(scot %p our.bowl)/[q.byk.bowl]/(scot %da now.bowl)/tests]
:: else cast path to ~[path] if needed
::
?@ +<.q.arg
[(tail !<([~ path] arg)) ~]
(tail !<([~ (list path)] arg))
@ -121,7 +121,7 @@
?^ fiz
;< cor=(unit vase) bind:m (build-file:strandio beam.i.fiz)
?~ cor
~> %slog.3^leaf+"FAILED {(spud s.beam.i.fiz)} (build)"
~> %slog.0^leaf+"FAILED {(spud s.beam.i.fiz)} (build)"
gather-tests(fiz t.fiz, build-ok |)
~> %slog.0^leaf+"built {(spud s.beam.i.fiz)}"
=/ arms=(list test-arm) (get-test-arms u.cor)
@ -137,6 +137,5 @@
|= [[=path =test-func] ok=_build-ok]
^+ ok
=/ res (run-test path test-func)
%- (%*(. slog pri ?:(ok.res 0 3)) output.res)
%- (%*(. slog pri ?:(ok.res 0 3)) result.res)
&(ok ok.res)
%- (slog (flop tang.res))
&(ok ok.res)

View File

@ -1,6 +1,6 @@
:: Print what your agent is doing.
::
/- verb
/- *verb
::
|= [loud=? =agent:gall]
=| bowl-print=_|
@ -14,7 +14,10 @@
^- (quip card:agent:gall agent:gall)
%- (print bowl |.("{<dap.bowl>}: on-init"))
=^ cards agent on-init:ag
[[(emit-event %on-init ~) cards] this]
:_ this
:_ :_ cards
(emit-event %on-init ~)
(emit-event-plus bowl [%on-init ~] cards)
::
++ on-save
^- vase
@ -26,7 +29,10 @@
^- (quip card:agent:gall agent:gall)
%- (print bowl |.("{<dap.bowl>}: on-load"))
=^ cards agent (on-load:ag old-state)
[[(emit-event %on-load ~) cards] this]
:_ this
:_ :_ cards
(emit-event %on-load ~)
(emit-event-plus bowl [%on-load ~] cards)
::
++ on-poke
|= [=mark =vase]
@ -38,17 +44,23 @@
%bowl `this(bowl-print !bowl-print)
==
=^ cards agent (on-poke:ag mark vase)
[[(emit-event %on-poke mark) cards] this]
:_ this
:_ :_ cards
(emit-event %on-poke mark)
(emit-event-plus bowl [%on-poke mark (mug q.vase)] cards)
::
++ on-watch
|= =path
^- (quip card:agent:gall agent:gall)
%- (print bowl |.("{<dap.bowl>}: on-watch on path {<path>}"))
=^ cards agent
?: ?=([%verb %events ~] path)
?: ?=([%verb ?(%events %events-plus) ~] path)
[~ agent]
(on-watch:ag path)
[[(emit-event %on-watch path) cards] this]
:_ this
:_ :_ cards
(emit-event %on-watch path)
(emit-event-plus bowl [%on-watch path] cards)
::
++ on-leave
|= =path
@ -57,7 +69,10 @@
?: ?=([%verb %event ~] path)
[~ this]
=^ cards agent (on-leave:ag path)
[[(emit-event %on-leave path) cards] this]
:_ this
:_ :_ cards
(emit-event %on-leave path)
(emit-event-plus bowl [%on-leave path] cards)
::
++ on-peek
|= =path
@ -70,7 +85,17 @@
^- (quip card:agent:gall agent:gall)
%- (print bowl |.("{<dap.bowl>}: on-agent on wire {<wire>}, {<-.sign>}"))
=^ cards agent (on-agent:ag wire sign)
[[(emit-event %on-agent wire -.sign) cards] this]
:_ this
:_ :_ cards
(emit-event %on-agent wire -.sign)
=; =^sign
(emit-event-plus bowl [%on-agent wire sign] cards)
?- -.sign
%poke-ack [%poke-ack ?=(~ p.sign)]
%watch-ack [%watch-ack ?=(~ p.sign)]
%kick [%kick ~]
%fact [%fact p.cage.sign (mug q.q.cage.sign)]
==
::
++ on-arvo
|= [=wire =sign-arvo]
@ -78,14 +103,20 @@
%- %+ print bowl |.
"{<dap.bowl>}: on-arvo on wire {<wire>}, {<[- +<]:sign-arvo>}"
=^ cards agent (on-arvo:ag wire sign-arvo)
[[(emit-event %on-arvo wire [- +<]:sign-arvo) cards] this]
:_ this
:_ :_ cards
(emit-event %on-arvo wire [- +<]:sign-arvo)
(emit-event-plus bowl [%on-arvo wire [- +<]:sign-arvo] cards)
::
++ on-fail
|= [=term =tang]
^- (quip card:agent:gall agent:gall)
%- (print bowl |.("{<dap.bowl>}: on-fail with term {<term>}"))
=^ cards agent (on-fail:ag term tang)
[[(emit-event %on-fail term) cards] this]
:_ this
:_ :_ cards
(emit-event %on-fail term)
(emit-event-plus bowl [%on-fail term] cards)
--
::
++ print
@ -99,7 +130,53 @@
same
::
++ emit-event
|= =event:verb
|= =event
^- card:agent:gall
[%give %fact ~[/verb/events] %verb-event !>(event)]
::
++ emit-event-plus
|= [=bowl:gall =cause cards=(list card:agent:gall)]
^- card:agent:gall
=; event=event-plus
[%give %fact ~[/verb/events-plus] %verb-event-plus !>(event)]
=- [act.bowl now.bowl src.bowl sap.bowl cause -]
%+ turn cards
|= =card:agent:gall
^- effect
::TODO for %fact, %kick, could calculate how many ships affected
?- card
[%pass * %agent * ?(%poke %poke-as) *]
=, q.card
=/ =cage ?-(-.task.q.card %poke cage.task, %poke-as [mark.task q.cage.task])
[%poke p.card [ship name] p.cage `@`(mug q.q.cage)]
::
[%pass * %agent * ?(%watch %watch-as) *]
=, q.card
=/ =path ?-(-.task.q.card %watch path.task, %watch-as path.task)
[%watch p.card [ship name] path]
::
[%pass * %agent * %leave *]
=, q.card
[%leave p.card [ship name]]
::
[%give %fact *]
=, p.card
[%fact paths p.cage (mug q.q.cage)]
::
[%give %kick *]
[%kick paths.p.card]
::
[%give ?(%poke-ack %watch-ack) *]
~| %explicit-ack
!! :: shouldn't be given explicitly
::
[%pass * %arvo *]
[%arvo p.card -.q.card +<.q.card]
::
[%pass *]
[%arvo p.card %$ -.q.card]
::
[%slip *]
$(card [%pass //slip p.card])
==
--

View File

@ -59,7 +59,7 @@
=/ ego (scot %p our)
=/ wen (scot %da now)
:* .^(rock:tire %cx /[ego]//[wen]/tire)
.^(=cone %cx /[ego]//[wen]/domes)
.^(cone %cx /[ego]//[wen]/domes)
.^((map desk [ship desk]) %gx /[ego]/hood/[wen]/kiln/sources/noun)
.^ (map [desk ship desk] sync-state) %gx
/[ego]/hood/[wen]/kiln/syncs/noun
@ -72,44 +72,73 @@
^- tang
=/ ego (scot %p our)
=/ wen (scot %da now)
=/ prep (report-prep our now)
?~ filt
=+ prep=[tyr cone sor zyn]=(report-prep our now)
?: =(%$ filt)
%- zing
%+ turn (flop desks)
%+ turn
?^ desks
(flop desks)
%+ sort ~(tap in ~(key by tyr.prep))
|= [a=desk b=desk]
?: |(=(a %kids) =(b %base)) &
?: |(=(a %base) =(b %kids)) |
(aor b a)
|=(syd=@tas (report-vat prep our now syd verb))
=/ deks
=/ deks=(list [=desk =zest wic=(set weft)])
?~ desks
%+ sort
(sort ~(tap by -.prep) |=([[a=@ *] b=@ *] !(aor a b)))
|=([[a=@ *] [b=@ *]] ?|(=(a %kids) =(b %base)))
%+ skip ~(tap by -.prep)
|=([syd=@tas *] =(~ (find ~[syd] desks)))
=. deks (skim deks |=([=desk *] ((sane %tas) desk)))
%+ sort ~(tap by tyr.prep)
|= [[a=desk *] [b=desk *]]
?: |(=(a %kids) =(b %base)) &
?: |(=(a %base) =(b %kids)) |
(aor b a)
%+ murn (flop desks)
|= des=desk
^- (unit [=desk =zest wic=(set weft)])
?~ got=(~(get by tyr.prep) des)
~
`[des u.got]
?: =(filt %blocking)
=/ base-wic
%+ sort ~(tap by wic:(~(got by -.prep) %base))
|=([[* a=@ud] [* b=@ud]] (gth a b))
?~ base-wic ~[leaf+"%base already up-to-date"]
=/ base-weft=(unit weft)
%- ~(rep in wic:(~(got by tyr.prep) %base))
|= [=weft out=(unit weft)]
?~ out
`weft
?: (lth num.weft num.u.out)
out
`weft
?~ base-weft ~['%base already up-to-date']
=/ blockers=(list desk)
%+ turn
%+ skip ~(tap in -.prep)
|= [* [zest=@tas wic=(set weft)]]
?. =(zest %live) &
(~(has in wic) i.base-wic)
|=([syd=desk *] syd)
?~ blockers ~[leaf+"No desks blocking upgrade, run |bump to apply"]
:- [%rose [" %" "To unblock upgrade run |suspend %" ""] blockers]
%+ sort
^- (list desk)
%+ murn deks
|= [=desk =zest wic=(set weft)]
^- (unit ^desk)
?. =(%live zest)
~
?: (~(has in wic) u.base-weft)
~
`desk
aor
?~ blockers ~['No desks blocking upgrade']
%- zing
%+ turn (flop blockers)
^- (list tang)
:- :~ %+ rap 3
:~ 'These desks are blocking upgrade to [%zuse '
(scot %ud num.u.base-weft)
']:'
== ==
%+ turn blockers
|=(syd=desk (report-vat prep our now syd verb))
::
%- zing
%+ turn
?+ filt !!
::
%exists
%+ skip deks
|=([syd=desk *] =(ud:.^(cass %cw /[ego]/[syd]/[wen]) 0))
|= [syd=desk *]
?~ got=(~(get by cone.prep) our syd)
&
=(0 let.u.got)
::
%running
%+ skim deks
@ -120,12 +149,17 @@
|= [syd=@tas [zest=@tas *]]
?| =(syd %kids)
=(zest %live)
=(ud:.^(cass %cw /[ego]/[syd]/[wen]) 0)
?~ got=(~(get by cone.prep) our syd)
&
=(0 let.u.got)
==
::
%exists-not
%+ skim deks
|=([syd=desk *] =(ud:.^(cass %cw /[ego]/[syd]/[wen]) 0))
|= [syd=desk *]
?~ got=(~(get by cone.prep) our syd)
|
=(0 let.u.got)
==
|=([syd=desk *] (report-vat prep our now syd verb))
:: +report-vat: report on a single desk installation
@ -136,34 +170,21 @@
==
our=ship now=@da syd=desk verb=?
==
^- tang
=- :: hack to force wrapped rendering
::
:: edg=6 empirically prevents dedent
::
%+ roll
(~(win re -) [0 6])
|=([a=tape b=(list @t)] [(crip a) b])
::
^- tank
|^ ^- tang
=/ ego (scot %p our)
=/ wen (scot %da now)
?. ((sane %tas) syd)
leaf+"insane desk: {<syd>}"
=+ .^(=cass %cw /[ego]/[syd]/[wen])
?: =(ud.cass 0)
leaf+"desk does not yet exist: {<syd>}"
?: =(%kids syd)
=+ .^(hash=@uv %cz /[ego]/[syd]/[wen])
leaf+"%kids %cz hash: {<hash>}"
=/ kel-path
/[ego]/[syd]/[wen]/sys/kelvin
?. .^(? %cu kel-path)
leaf+"bad desk: {<syd>}"
=+ .^(=waft %cx kel-path)
:+ %rose ["" "{<syd>}" "::"]
^- tang
~[(cat 3 'insane desk: %' syd)]
?. (~(has by cone) our syd)
~[(cat 3 'desk does not yet exist: %' syd)]
=/ hash .^(@uv %cz /[ego]/[syd]/[wen])
?: =(%kids syd)
~[(cat 3 '%kids %cz hash: ' (scot %uv hash))]
=/ kel-path /[ego]/[syd]/[wen]/sys/kelvin
?. .^(? %cu kel-path)
~[(cat 3 'bad desk: %' syd)]
=+ .^(=waft %cx kel-path)
^- tang
=/ =sink
?~ s=(~(get by sor) syd)
~
@ -171,52 +192,100 @@
~
`[p.u.s q.u.s [kid let]:u.z]
=/ meb=(list @uv)
?~ sink [hash]~
(mergebase-hashes our syd now her.u.sink sud.u.sink)
?~ sink ~[hash]
%+ turn
.^ (list tako) %cs
/[ego]/[syd]/[wen]/base/(scot %p her.u.sink)/[sud.u.sink]
==
|=(=tako .^(@uv %cs /[ego]/[syd]/[wen]/hash/(scot %uv tako)))
=/ dek (~(got by tyr) syd)
=/ sat
?- zest.dek
%live "running"
%dead "suspended"
%held "suspended until next update"
%live 'running'
%dead 'suspended'
%held 'suspended until next update'
==
=/ kul=tape
%+ roll
%+ sort
~(tap in (waft-to-wefts:clay waft))
|= [a=weft b=weft]
?: =(lal.a lal.b)
(lte num.a num.b)
(lte lal.a lal.b)
|= [=weft =tape]
(welp " {<[lal num]:weft>}" tape)
=/ kul=cord (print-wefts (waft-to-wefts waft))
?. verb
:~ leaf/"/sys/kelvin: {kul}"
leaf/"%cz hash ends in: {(truncate-hash hash)}"
leaf/"app status: {sat}"
leaf/"source ship: {?~(sink <~> <her.u.sink>)}"
leaf/"pending updates: {<`(list [@tas @ud])`~(tap in wic.dek)>}"
:~ '::'
(cat 3 ' pending updates: ' (print-wefts wic.dek))
(cat 3 ' source ship: ' ?~(sink '~' (scot %p her.u.sink)))
(cat 3 ' app status: ' sat)
(cat 3 ' %cz hash ends in: ' (print-shorthash hash))
(cat 3 ' /sys/kelvin: ' (print-wefts (waft-to-wefts waft)))
(cat 3 '%' syd)
==
::
=/ [on=(list [@tas ?]) of=(list [@tas ?])]
=/ =dome (~(got by cone) our syd)
(skid ~(tap by ren.dome) |=([* ?] +<+))
:~ leaf/"/sys/kelvin: {kul}"
leaf/"base hash: {?.(=(1 (lent meb)) <meb> <(head meb)>)}"
leaf/"%cz hash: {<hash>}"
::
leaf/"app status: {sat}"
leaf/"force on: {<(sort (turn on head) aor)>}"
leaf/"force off: {<(sort (turn of head) aor)>}"
::
leaf/"publishing ship: {?~(sink <~> <(get-publisher our syd now)>)}"
leaf/"updates: {?~(sink "local" "remote")}"
leaf/"source ship: {?~(sink <~> <her.u.sink>)}"
leaf/"source desk: {?~(sink <~> <sud.u.sink>)}"
leaf/"source aeon: {?~(sink <~> <let.u.sink>)}"
leaf/"kids desk: {?~(sink <~> ?~(kid.u.sink <~> <u.kid.u.sink>))}"
leaf/"pending updates: {<`(list [@tas @ud])`~(tap in wic.dek)>}"
=/ [on=(list @tas) of=(list @tas)]
=/ [on=(list @tas) of=(list @tas)]
%- ~(rep by ren:(~(got by cone) our syd))
|= [[=dude:gall is-on=?] on=(list @tas) of=(list @tas)]
?: is-on
[[dude on] of]
[on [dude of]]
[(sort on aor) (sort of aor)]
:~ '::'
(cat 3 ' pending updates: ' (print-wefts wic.dek))
%^ cat 3 ' kids desk: ' ?~ sink '~'
?~ kid.u.sink '~'
(cat 3 '%' u.kid.u.sink)
(cat 3 ' source aeon: ' ?~(sink '~' (scot %ud let.u.sink)))
(cat 3 ' source desk: ' ?~(sink '~' (cat 3 '%' sud.u.sink)))
(cat 3 ' source ship: ' ?~(sink '~' (scot %p her.u.sink)))
(cat 3 ' updates: ' ?~(sink 'local' 'remote'))
%^ cat 3 ' publishing ship: ' ?~ got=(get-publisher our syd now)
'~'
(scot %p u.got)
::
(cat 3 ' force off: ' (print-agents of))
(cat 3 ' force on: ' (print-agents on))
(cat 3 ' app status: ' sat)
::
(cat 3 ' %cz hash: ' (scot %uv hash))
(cat 3 ' base hash: ' (print-mergebases meb))
(cat 3 ' /sys/kelvin: ' (print-wefts (waft-to-wefts waft)))
(cat 3 '%' syd)
==
++ print-wefts
|= wefts=(set weft)
^- @t
?: =(~ wefts)
'~'
%+ roll (sort ~(tap in wefts) aor)
|= [=weft out=@t]
?: =('' out)
(rap 3 '[%' lal.weft ' ' (scot %ud num.weft) ']' ~)
(rap 3 out ' [%' lal.weft ' ' (scot %ud num.weft) ']' ~)
::
++ print-shorthash
|= hash=@uv
^- @t
(crip ((v-co:co 5) (end [0 25] hash)))
::
++ print-mergebases
|= hashes=(list @uv)
^- @t
?~ hashes
'~'
?~ t.hashes
(scot %uv i.hashes)
%+ roll `(list @uv)`hashes
|= [hash=@uv out=@t]
?: =('' out)
(print-shorthash hash)
(rap 3 out ' ' (print-shorthash hash) ~)
::
++ print-agents
|= agents=(list @tas)
^- @t
?~ agents
'~'
%+ roll `(list @tas)`agents
|= [agent=@tas out=@tas]
?: =('' out)
(cat 3 '%' agent)
(rap 3 out ' %' agent ~)
--
:: +report-kids: non-vat cz hash report for kids desk
::
++ report-kids
@ -226,9 +295,9 @@
=/ ego (scot %p our)
=/ wen (scot %da now)
?. (~(has in .^((set desk) %cd /[ego]//[wen])) syd)
leaf/"no %kids desk"
'no %kids desk'
=+ .^(hash=@uv %cz /[ego]/[syd]/[wen])
leaf/"%kids %cz hash: {<hash>}"
(cat 3 '%kids %cz hash: ' (scot %uv hash))
:: +read-bill-foreign: read /desk/bill from a foreign desk
::
++ read-bill-foreign
@ -288,8 +357,8 @@
=/ her (scot %p her)
=/ ego (scot %p our)
=/ wen (scot %da now)
%+ turn .^((list tako) %cs ~[ego syd wen %base her sud])
|=(=tako .^(@uv %cs ~[ego syd wen %hash (scot %uv tako)]))
%+ turn .^((list tako) %cs /[ego]/[syd]/[wen]/base/[her]/[sud])
|=(=tako .^(@uv %cs /[ego]/[syd]/[wen]/hash/(scot %uv tako)))
::
++ enjs
=, enjs:format

View File

@ -9,4 +9,40 @@
[%on-arvo =wire vane=term sign=term]
[%on-fail =term]
==
--
::
+$ event-plus
$: act=@ud
now=@da
src=@p
sap=path
=cause
effects=(list effect)
==
::
+$ cause
$% [%on-init ~]
[%on-load ~]
[%on-poke =mark mug=@ux]
[%on-watch =path]
[%on-leave =path]
[%on-agent =wire =sign]
[%on-arvo =wire vane=term sign=term]
[%on-fail =term]
==
::
+$ sign
$% [%poke-ack ack=?]
[%watch-ack ack=?]
[%kick ~]
[%fact =mark mug=@ux]
==
::
+$ effect
$% [%poke =wire =gill:gall =mark mug=@ux]
[%watch =wire =gill:gall =path]
[%leave =wire =gill:gall]
[%fact paths=(list path) =mark mug=@ux]
[%kick paths=(list path)]
[%arvo =wire vane=term task=term]
==
--

View File

@ -1,183 +0,0 @@
var gulp = require('gulp');
var cssimport = require('gulp-cssimport');
var rollup = require('gulp-better-rollup');
var cssnano = require('cssnano');
var postcss = require('gulp-postcss');
var sucrase = require('@sucrase/gulp-plugin');
var minify = require('gulp-minify');
var rename = require('gulp-rename');
var del = require('del');
var resolve = require('rollup-plugin-node-resolve');
var commonjs = require('rollup-plugin-commonjs');
var rootImport = require('rollup-plugin-root-import');
var globals = require('rollup-plugin-node-globals');
/***
Main config options
***/
var urbitrc = require('../urbitrc');
/***
End main config options
***/
gulp.task('css-bundle', function() {
let plugins = [
cssnano()
];
return gulp
.src('src/index.css')
.pipe(cssimport())
.pipe(postcss(plugins))
.pipe(gulp.dest('../../arvo/app/debug/css'));
});
gulp.task('jsx-transform', function(cb) {
return gulp.src('src/**/*.js')
.pipe(sucrase({
transforms: ['jsx']
}))
.pipe(gulp.dest('dist'));
});
gulp.task('tile-jsx-transform', function(cb) {
return gulp.src('tile/**/*.js')
.pipe(sucrase({
transforms: ['jsx']
}))
.pipe(gulp.dest('dist'));
});
gulp.task('js-imports', function(cb) {
return gulp.src('dist/index.js')
.pipe(rollup({
plugins: [
commonjs({
namedExports: {
'node_modules/react/index.js': [ 'Component', 'createRef', 'createElement', 'useState', 'useRef', 'useEffect', 'Fragment' ],
'node_modules/react-is/index.js': [ 'isValidElementType' ],
}
}),
rootImport({
root: `${__dirname}/dist/js`,
useEntry: 'prepend',
extensions: '.js'
}),
globals(),
resolve()
]
}, 'umd'))
.on('error', function(e){
console.log(e);
cb();
})
.pipe(gulp.dest('../../arvo/app/debug/js/'))
.on('end', cb);
});
gulp.task('tile-js-imports', function(cb) {
return gulp.src('dist/tile.js')
.pipe(rollup({
plugins: [
commonjs({
namedExports: {
'node_modules/react/index.js': [ 'Component' ],
}
}),
rootImport({
root: `${__dirname}/dist/js`,
useEntry: 'prepend',
extensions: '.js'
}),
globals(),
resolve()
]
}, 'umd'))
.on('error', function(e){
console.log(e);
cb();
})
.pipe(gulp.dest('../../arvo/app/debug/js/'))
.on('end', cb);
});
gulp.task('js-minify', function () {
return gulp.src('../../arvo/app/debug/js/index.js')
.pipe(minify())
.pipe(gulp.dest('../../arvo/app/debug/js/'));
});
gulp.task('tile-js-minify', function () {
return gulp.src('../../arvo/app/debug/js/tile.js')
.pipe(minify())
.pipe(gulp.dest('../../arvo/app/debug/js/'));
});
gulp.task('rename-index-min', function() {
return gulp.src('../../arvo/app/debug/js/index-min.js')
.pipe(rename('index.js'))
.pipe(gulp.dest('../../arvo/app/debug/js/'))
});
gulp.task('rename-tile-min', function() {
return gulp.src('../../arvo/app/debug/js/tile-min.js')
.pipe(rename('tile.js'))
.pipe(gulp.dest('../../arvo/app/debug/js/'))});
gulp.task('clean-min', function() {
return del(['../../arvo/app/debug/js/index-min.js', '../../arvo/app/debug/js/tile-min.js'], {force: true})
});
gulp.task('urbit-copy', function () {
let ret = gulp.src('../../arvo/**/*');
urbitrc.URBIT_PIERS.forEach(function(pier) {
ret = ret.pipe(gulp.dest(pier));
});
return ret;
});
gulp.task('js-bundle-dev', gulp.series('jsx-transform', 'js-imports'));
gulp.task('tile-js-bundle-dev', gulp.series('tile-jsx-transform', 'tile-js-imports'));
gulp.task('js-bundle-prod', gulp.series('jsx-transform', 'js-imports', 'js-minify'))
gulp.task('tile-js-bundle-prod',
gulp.series('tile-jsx-transform', 'tile-js-imports', 'tile-js-minify'));
gulp.task('bundle-dev',
gulp.series(
gulp.parallel(
'css-bundle',
'js-bundle-dev',
'tile-js-bundle-dev'
),
'urbit-copy'
)
);
gulp.task('bundle-prod',
gulp.series(
gulp.parallel(
'css-bundle',
'js-bundle-prod',
'tile-js-bundle-prod',
),
'rename-index-min',
'rename-tile-min',
'clean-min',
'urbit-copy'
)
);
gulp.task('default', gulp.series('bundle-dev'));
gulp.task('watch', gulp.series('default', function() {
gulp.watch('tile/**/*.js', gulp.parallel('tile-js-bundle-dev'));
gulp.watch('src/**/*.js', gulp.parallel('js-bundle-dev'));
gulp.watch('src/**/*.css', gulp.parallel('css-bundle'));
gulp.watch('../../arvo/**/*', gulp.parallel('urbit-copy'));
}));

View File

@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Debug Dashboard</title>
<style type="text/css" src="/src/index.css"></style>
</head>
<body>
<div id="root"></div>
<script src="/~debug/channel.js"></script>
<script src="/~debug/js/session.js"></script>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -1,43 +1,32 @@
{
"name": "urbit-apps",
"version": "1.0.0",
"description": "",
"main": "index.js",
"name": "debug-dashboard",
"private": true,
"version": "2.0.0",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@sucrase/gulp-plugin": "^2.0.0",
"cssnano": "^4.1.10",
"gulp": "^4.0.0",
"gulp-better-rollup": "^4.0.1",
"gulp-cssimport": "^7.0.0",
"gulp-minify": "^3.1.0",
"gulp-postcss": "^8.0.0",
"gulp-rename": "^1.4.0",
"moment": "^2.24.0",
"rollup": "^1.6.0",
"rollup-plugin-commonjs": "^9.2.0",
"rollup-plugin-node-globals": "^1.4.0",
"rollup-plugin-node-resolve": "^4.0.0",
"rollup-plugin-root-import": "^0.2.3",
"sucrase": "^3.8.0"
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"@gitgraph/react": "^1.5.4",
"classnames": "^2.2.6",
"del": "^5.1.0",
"lodash": "^4.17.11",
"mousetrap": "^1.6.3",
"react": "^16.5.2",
"react-dom": "^16.8.6",
"react-router-dom": "^5.0.0",
"urbit-ob": "^5.0.0",
"urbit-sigil-js": "^1.3.2"
"@gitgraph/react": "^1.6.0",
"file-system-access": "^1.0.4",
"lodash": "^4.17.21",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"urbit-ob": "^5.0.1"
},
"resolutions": {
"natives": "1.1.3"
"devDependencies": {
"@types/react": "^18.2.66",
"@types/react-dom": "^18.2.22",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0",
"@vitejs/plugin-react": "^4.2.1",
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6",
"typescript": "^5.2.2",
"vite": "^5.2.0"
}
}

View File

@ -0,0 +1,292 @@
class Channel {
constructor() {
this.init();
this.deleteOnUnload();
// a way to handle channel errors
//
//
this.onChannelError = (err) => {
console.error('event source error: ', err);
};
this.onChannelOpen = (e) => {
console.log('open', e);
};
}
init() {
this.debounceInterval = 500;
// unique identifier: current time and random number
//
this.uid =
new Date().getTime().toString() +
"-" +
Math.random().toString(16).slice(-6);
this.requestId = 1;
// the currently connected EventSource
//
this.eventSource = null;
// the id of the last EventSource event we received
//
this.lastEventId = 0;
// this last event id acknowledgment sent to the server
//
this.lastAcknowledgedEventId = 0;
// a registry of requestId to successFunc/failureFunc
//
// These functions are registered during a +poke and are executed
// in the onServerEvent()/onServerError() callbacks. Only one of
// the functions will be called, and the outstanding poke will be
// removed after calling the success or failure function.
//
this.outstandingPokes = new Map();
// a registry of requestId to subscription functions.
//
// These functions are registered during a +subscribe and are
// executed in the onServerEvent()/onServerError() callbacks. The
// event function will be called whenever a new piece of data on this
// subscription is available, which may be 0, 1, or many times. The
// disconnect function may be called exactly once.
//
this.outstandingSubscriptions = new Map();
this.outstandingJSON = [];
this.debounceTimer = null;
}
resetDebounceTimer() {
if (this.debounceTimer) {
clearTimeout(this.debounceTimer);
this.debounceTimer = null;
}
this.debounceTimer = setTimeout(() => {
this.sendJSONToChannel();
}, this.debounceInterval)
}
setOnChannelError(onError = (err) => {}) {
this.onChannelError = onError;
}
setOnChannelOpen(onOpen = (e) => {}) {
this.onChannelOpen = onOpen;
}
deleteOnUnload() {
window.addEventListener("beforeunload", (event) => {
this.delete();
});
}
clearQueue() {
clearTimeout(this.debounceTimer);
this.debounceTimer = null;
this.sendJSONToChannel();
}
// sends a poke to an app on an urbit ship
//
poke(ship, app, mark, json, successFunc, failureFunc) {
let id = this.nextId();
this.outstandingPokes.set(
id,
{
success: successFunc,
fail: failureFunc
}
);
const j = {
id,
action: "poke",
ship,
app,
mark,
json
};
this.sendJSONToChannel(j);
}
// subscribes to a path on an specific app and ship.
//
// Returns a subscription id, which is the same as the same internal id
// passed to your Urbit.
subscribe(
ship,
app,
path,
connectionErrFunc = () => {},
eventFunc = () => {},
quitFunc = () => {},
subAckFunc = () => {},
) {
let id = this.nextId();
this.outstandingSubscriptions.set(
id,
{
err: connectionErrFunc,
event: eventFunc,
quit: quitFunc,
subAck: subAckFunc
}
);
const json = {
id,
action: "subscribe",
ship,
app,
path
}
this.resetDebounceTimer();
this.outstandingJSON.push(json);
return id;
}
// quit the channel
//
delete() {
let id = this.nextId();
clearInterval(this.ackTimer);
navigator.sendBeacon(this.channelURL(), JSON.stringify([{
id,
action: "delete"
}]));
if (this.eventSource) {
this.eventSource.close();
}
}
// unsubscribe to a specific subscription
//
unsubscribe(subscription) {
let id = this.nextId();
this.sendJSONToChannel({
id,
action: "unsubscribe",
subscription
});
}
// sends a JSON command command to the server.
//
sendJSONToChannel(j) {
let req = new XMLHttpRequest();
req.open("PUT", this.channelURL());
req.setRequestHeader("Content-Type", "application/json");
if (this.lastEventId == this.lastAcknowledgedEventId) {
if (j) {
this.outstandingJSON.push(j);
}
if (this.outstandingJSON.length > 0) {
let x = JSON.stringify(this.outstandingJSON);
req.send(x);
}
} else {
// we add an acknowledgment to clear the server side queue
//
// The server side puts messages it sends us in a queue until we
// acknowledge that we received it.
//
let payload = [
...this.outstandingJSON,
{action: "ack", "event-id": this.lastEventId}
];
if (j) {
payload.push(j)
}
let x = JSON.stringify(payload);
req.send(x);
this.lastAcknowledgedEventId = this.lastEventId;
}
this.outstandingJSON = [];
this.connectIfDisconnected();
}
// connects to the EventSource if we are not currently connected
//
connectIfDisconnected() {
if (this.eventSource) {
return;
}
this.eventSource = new EventSource(this.channelURL(), {withCredentials:true});
this.eventSource.onmessage = e => {
this.lastEventId = parseInt(e.lastEventId, 10);
let obj = JSON.parse(e.data);
let pokeFuncs = this.outstandingPokes.get(obj.id);
let subFuncs = this.outstandingSubscriptions.get(obj.id);
if (obj.response == "poke" && !!pokeFuncs) {
let funcs = pokeFuncs;
if (obj.hasOwnProperty("ok")) {
funcs["success"]();
} else if (obj.hasOwnProperty("err")) {
funcs["fail"](obj.err);
} else {
console.error("Invalid poke response: ", obj);
}
this.outstandingPokes.delete(obj.id);
} else if (obj.response == "subscribe" ||
(obj.response == "poke" && !!subFuncs)) {
let funcs = subFuncs;
if (obj.hasOwnProperty("err")) {
funcs["err"](obj.err);
this.outstandingSubscriptions.delete(obj.id);
} else if (obj.hasOwnProperty("ok")) {
funcs["subAck"](obj);
}
} else if (obj.response == "diff") {
// ensure we ack before channel clogs
if((this.lastEventId - this.lastAcknowledgedEventId) > 30) {
this.clearQueue();
}
let funcs = subFuncs;
funcs["event"](obj.json);
} else if (obj.response == "quit") {
let funcs = subFuncs;
funcs["quit"](obj);
this.outstandingSubscriptions.delete(obj.id);
} else {
console.log("Unrecognized response: ", e);
}
}
this.eventSource.onopen = this.onChannelOpen;
this.eventSource.onerror = e => {
this.delete();
this.init();
this.onChannelError(e);
}
}
channelURL() {
return "/~/channel/" + this.uid;
}
nextId() {
return this.requestId++;
}
}
window.channel = Channel;

View File

@ -3,6 +3,7 @@ html, body {
width: 100%;
-webkit-font-smoothing: antialiased;
overflow: hidden;
background-color: white;
}
p, h1, h2, h3, h4, h5, h6, a, input, textarea, button {

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,73 @@
#viewport {
position: relative;
width: 100%;
padding-top: 1em;
border: 1px solid black;
font-family: monospace;
}
#controls input {
width: 100%;
}
.agent {
position: relative;
padding-left: 1em;
width: calc(100% - 1em);
border-top: 2px solid black;
margin-top: 2em;
}
.cause {
position: relative;
width: 100%;
height: 5em;
border-top: 1px solid grey;
}
.legend {
position: absolute;
left: -1em;
width: auto;
height: auto;
text-orientation: sideways;
writing-mode: vertical-rl;
text-wrap: nowrap;
}
.event {
position: absolute;
width: 1em;
height: 1em;
border-radius: 50%;
background-color: rgba(0, 0, 0, 0.2);
border: 1px dotted rgba(0,0,0,0);
}
.event.effects {
border-style: solid;
}
.details {
padding: 0.3em;
display: none;
position: absolute;
top: 0.75em;
left: 0.75em;
z-index: 2;
min-width: 20em;
display: none;
overflow: visible;
border: 1px solid black;
background-color: white;
}
.event.right .details {
left: initial;
right: 0.75em;
}
.event:hover .details, .event.focus .details {
display: block;
}
.event:hover, .event.focus {
box-shadow: 0 0 10px 0 #f30;
}
.event details {
padding-left: 1em;
}
.event details summary {
position: relative;
left: -1em;
}

View File

@ -1,4 +1,4 @@
@import "css/indigo-static.css";
@import "css/fonts.css";
@import "css/custom.css";
@import "css/logs.css";

View File

@ -1,17 +0,0 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Root } from '/components/root';
import { api } from '/api';
import { store } from '/store';
import { subscription } from "/subscription";
api.setAuthTokens({
ship: window.ship
});
window.urb = new window.channel();
subscription.start();
ReactDOM.render((
<Root />
), document.querySelectorAll("#root")[0]);

View File

@ -1,7 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import _ from 'lodash';
import { store } from '/store';
import { store } from './store';
import moment from 'moment';
import { stringToTa } from './lib/util';
@ -72,6 +72,42 @@ class UrbitApi {
);
}
bindToVerbPlus(app) {
return this.bind('/verb/events-plus', 'PUT', this.authTokens.ship, app,
(result) => {
result.data.app = app;
store.handleEvent({ data: { local: { verbEventPlus: {
gill: `~${this.authTokens.ship}/${app}`,
log: result.data
} } } });
},
() => {
store.handleEvent({
data: {
local: {
verbStatus: {
app: app,
msg: 'failed to establish verb+ connection to ' + app
}
}
}
});
},
() => {
store.handleEvent({
data: {
local: {
verbStatus: {
app: app,
msg: 'verb+ connection to ' + app + ' was dropped'
}
}
}
});
}
);
}
getJson(path, localTransform, onFail) {
let source = '/~debug' + path + '.json';
const query = window.location.href.split('?')[1];
@ -201,6 +237,13 @@ class UrbitApi {
);
}
getCache() {
this.getJson('/eyre/cache',
this.wrapLocal('eyreCache'),
this.showStatus('error fetching eyre cache')
);
}
getConnections() {
this.getJson('/eyre/connections',
this.wrapLocal('eyreConnections'),
@ -222,6 +265,11 @@ class UrbitApi {
);
}
clearCache(url) {
return this.action("dbug", "json", { 'clear-eyre-cache': { url: url } })
.then(this.getCache.bind(this));
}
// local
sidebarToggle() {

View File

@ -3,17 +3,18 @@ import { BrowserRouter, Switch, Route, Link } from "react-router-dom";
import classnames from 'classnames';
import _ from 'lodash';
import { api } from '/api';
import { subscription } from '/subscription';
import { store } from '/store';
import { Skeleton } from '/components/skeleton';
import { MessageScreen } from '/components/message-screen';
import { Apps } from '/views/apps';
import { Spider } from '/views/spider';
import { Ames } from '/views/ames';
import { Behn } from '/views/behn';
import { Clay } from '/views/clay';
import { Eyre } from '/views/eyre';
import { api } from '../api';
import { subscription } from '../subscription';
import { store } from '../store';
import { Skeleton } from '../components/skeleton';
import { MessageScreen } from '../components/message-screen';
import { Apps } from '../views/apps';
import { Logs } from '../views/logs';
import { Spider } from '../views/spider';
import { Ames } from '../views/ames';
import { Behn } from '../views/behn';
import { Clay } from '../views/clay';
import { Eyre } from '../views/eyre';
import { makeRoutePath } from '../lib/util';
export class Root extends Component {
@ -54,6 +55,16 @@ export class Root extends Component {
}}
/>
<Route exact path={makeRoutePath('logs')}
render={(props) => {
return (
<Skeleton status={state.status} selected="logs">
<Logs logs={state.logs} {...props} />
</Skeleton>
);
}}
/>
<Route exact path={makeRoutePath('spider')}
render={(props) => {
return (
@ -100,6 +111,7 @@ export class Root extends Component {
<Skeleton status={state.status} selected="eyre">
<Eyre
bindings={state.bindings}
cache={state.cache}
connections={state.connections}
authentication={state.authentication}
channels={state.channels}

View File

@ -43,7 +43,10 @@ export class SearchableList extends Component {
return (<div style={{position: 'relative', border: '1px solid grey', padding: '4px'}}>
{props.children}
<div>{searchBar} ({items.length})</div>
<div>{items.length === 0 ? 'none' : items}</div>
<details open={(props.open === undefined) ? true : props.open}>
<summary>{items.length} items</summary>
<div>{items.length === 0 ? 'none' : items}</div>
</details>
</div>);
}
}

View File

@ -27,6 +27,7 @@ export class Skeleton extends Component {
let items = [
'apps',
'logs',
'spider',
'ames',
'behn',

View File

@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { SearchableList } from '../components/searchable-list';
import { SearchableList } from './searchable-list';
import { renderDuct } from '../lib/util';
export class Subscriptions extends Component {
@ -65,4 +65,4 @@ export class Subscriptions extends Component {
}
}
export default Links;
export default Subscriptions;

View File

@ -13,7 +13,7 @@ export function makeRoutePath(resource, includeQuery = false) {
export function msToDa(ms, mil) {
const d = new Date(ms);
var fil = function(n) {
const fil = function(n) {
return n >= 10 ? n : "0" + n;
};
return (
@ -23,7 +23,10 @@ export function msToDa(ms, mil) {
`${fil(d.getUTCHours())}.` +
`${fil(d.getUTCMinutes())}.` +
`${fil(d.getUTCSeconds())}` +
`${mil ? "..0000" : ""}`
//NOTE poor man's pretty @da milliseconds
`${!mil ? '' :
'..' + Math.floor((d.getUTCMilliseconds() / 1000) * 0x10000)
.toString(16).padStart(4, '0')}`
);
}

View File

@ -12,6 +12,7 @@ export class LocalReducer {
this.appFailed(data, state);
this.verbResult(data, state);
this.verbStatus(data, state);
this.verbEventPlus(data, state);
//
this.threads(data, state);
//
@ -23,6 +24,7 @@ export class LocalReducer {
this.clayCommits(data, state);
//
this.eyreBindings(data, state);
this.eyreCache(data, state);
this.eyreConnections(data, state);
this.eyreAuthentication(data, state);
this.eyreChannels(data, state);
@ -102,6 +104,26 @@ export class LocalReducer {
}
}
verbEventPlus(obj, state) {
const data = _.get(obj, 'verbEventPlus', false);
if (data) {
//NOTE this is just a store.addLogs() that makes some assumptions
if (!state.logs[data.gill]) {
state.logs[data.gill] = {
logs: [data.log],
oldest: data.log.now,
newest: data.log.now,
};
state.logsRange.oldest = Math.min(state.logsRange.oldest || data.log.now, data.log.now);
state.logsRange.newest = data.log.now;
} else {
state.logs[data.gill].logs.push(data.log);
state.logs[data.gill].newest = data.log.now;
state.logsRange.newest = data.log.now;
}
}
}
// spider
threads(obj, state) {
@ -156,6 +178,13 @@ export class LocalReducer {
}
}
eyreCache(obj, state) {
const data = _.get(obj, 'eyreCache', false);
if (data) {
state.cache = data;
}
}
eyreConnections(obj, state) {
const data = _.get(obj, 'eyreConnections', false);
if (data) {

View File

@ -1,4 +1,4 @@
import { LocalReducer } from '/reducers/local.js';
import { LocalReducer } from './reducers/local.js';
import _ from 'lodash';
class Store {
@ -6,11 +6,14 @@ class Store {
this.state = {
status: null,
apps: {},
logs: {},
logsRange: { oldest: null, newest: null },
threads: {},
peers: { known: [], alien: [], deets: {}},
timers: [],
commits: [],
bindings: [],
cache: [],
connections: [],
authentication: {
sessions: [],
@ -42,6 +45,41 @@ class Store {
this.setState(this.state);
}
addLogs(gill, start, newLogs) {
let agent = this.state.logs[gill];
let logsRange = this.state.logsRange;
if (!agent) {
agent = {
logs: newLogs,
oldest: newLogs[0].now,
newest: newLogs[newLogs.length - 1].now,
}
logsRange.oldest = Math.min(logsRange.oldest || agent.oldest, agent.oldest);
logsRange.newest = Math.max(logsRange.newest || agent.newest, agent.newest);
} else if (start < (agent.oldest || start + 1)) {
agent.logs = [...newLogs, ...agent.logs];
agent.oldest = newLogs[0].now;
logsRange.oldest = Math.min(logsRange.oldest || agent.oldest, agent.oldest);
} else if (start > agent.newest) {
agent.logs = [...agent.logs, ...newLogs];
agent.newest = newLogs[newLogs.length - 1].now;
logsRange.newest = Math.max(logsRange.newest || agent.newest, agent.newest);
} else {
console.log(`assuming duplicate load for ${gill}, ignoring logs at ${start}`);
}
this.state.logs[gill] = agent;
this.state.logsRange = logsRange;
this.setState(this.state);
}
clearLogs() {
this.state.logs = {};
this.state.logsRange = { oldest: null, newest: null };
this.setState(this.state);
}
}
export let store = new Store();

View File

@ -1,5 +1,5 @@
import { api } from '/api';
import { store } from '/store';
import { api } from './api';
import { store } from './store';
export class Subscription {
start() {

View File

@ -46,16 +46,6 @@ export class Ames extends Component {
return <SearchableList placeholder="path" items={items}/>;
}
renderDucts(ducts) {
const items = ducts.map(duct => {
return {
key: duct.join(' '),
jsx: (<div>{renderDuct(duct)}</div>)
}
});
return <SearchableList placeholder="duct" items={items}/>
}
renderSnd(snd) {
const unsent = snd['unsent-messages'].reduce((a, b) => {
return a + b + ' bytes, ';
@ -309,7 +299,6 @@ export class Ames extends Component {
return (<>
Pending messages: {peer.alien.messages}
Pending packets: {peer.alien.packets}
Heeds: {this.renderDucts(peer.alien.heeds)}
Keens: {this.renderPaths(peer.alien.keens)}
</>);
} else if (peer.known) {
@ -373,11 +362,6 @@ export class Ames extends Component {
<SearchableList placeholder="bone" items={naxItems} />
</>);
const heeds = (<>
<h4 style={{marginTop: '1em'}}>heeds</h4>
{this.renderDucts(p.heeds)}
</>);
const scryItems = p.scries.map(this.renderScry);
const scry = (<>
<h4 style={{marginTop: '1em'}}>scries</h4>
@ -395,7 +379,6 @@ export class Ames extends Component {
{forward}
{backward}
{nax}
{heeds}
{scry}
</>);
} else {

View File

@ -94,11 +94,13 @@ export class Apps extends Component {
<pre>{(data.state || data.simpleState).join('\n')}</pre>
</div>
<div>
<Subscriptions {...data.subscriptions} />
<button onClick={() => { api.bindToVerb(app) }}>listen to simple verb (here)</button>
{' '}
<button onClick={() => { api.bindToVerbPlus(app) }}>listen to verb+ (logs viewer)</button>
<SearchableList placeholder="event description" items={events} />
</div>
<div>
<button onClick={()=>{api.bindToVerb(app)}}>listen to verb</button>
<SearchableList placeholder="event description" items={events} />
<Subscriptions {...data.subscriptions} />
</div>
</>)
}

View File

@ -12,6 +12,7 @@ export class Eyre extends Component {
this.state = {};
this.loadBindings = this.loadBindings.bind(this);
this.loadCache = this.loadCache.bind(this);
this.loadConnections = this.loadConnections.bind(this);
this.loadAuthenticationState = this.loadAuthenticationState.bind(this);
this.loadChannels = this.loadChannels.bind(this);
@ -20,6 +21,7 @@ export class Eyre extends Component {
componentDidMount() {
const { props } = this;
if (props.bindings.length === 0) this.loadBindings();
if (props.cache.length === 0) this.loadCache();
if (props.connections.length == 0) this.loadConnections();
if (props.authentication.sessions.length == 0) this.loadAuthenticationState();
if (props.channels.length == 0) this.loadChannels();
@ -34,6 +36,14 @@ export class Eyre extends Component {
api.getBindings();
}
loadCache() {
api.getCache();
}
clearCache(url) {
api.clearCache(url);
}
loadConnections() {
api.getConnections();
}
@ -61,6 +71,36 @@ export class Eyre extends Component {
</div>)};
});
const cacheItems = props.cache.map(entry => {
return {key: entry.url + ' ' + (entry.val ? 'LIVE' : 'CLEARED'), jsx: (<div class="flex" style={{ marginBottom: '3px' }}>
<div style={{ width: '45%' }}>
{entry.url}
</div>
<div style={{ width: '5%' }}>
(v{entry.aeon})
</div>
{ !entry.val ? 'cleared' :
<div style={{ width: '50%', position: 'relative' }}>
<div style={{ display: 'inline-block', width: '10%' }}>
{entry.val.auth ? 'auth' : 'free'}
</div>
<div style={{ display: 'inline-block', width: '10%' }}>
{entry.val.payload.status}
</div>
<div style={{ display: 'inline-block', width: '50%' }}>
{entry.val.payload.headers.reduce((o, h) => (o ? o+'; ': '') + h.key + '=' + h.value, '')}
</div>
<div style={{ display: 'inline-block', width: '25%' }}>
{entry.val.payload.data ? entry.val.payload.data.toLocaleString('de-DE')+' bytes' : 'no data'}
</div>
<div style={{ display: 'inline-block', width: '5%' }}>
<button onClick={() => { this.clearCache(entry.url) }}>clear</button>
</div>
</div>
}
</div>)};
})
const connectionItems = props.connections.map(c => {
return {key: c.duct + ' ' + c.action, jsx: (
<table style={{borderBottom: '1px solid black'}}><tbody>
@ -232,6 +272,14 @@ export class Eyre extends Component {
<button onClick={this.loadBindings}>refresh</button>
</SearchableList>
<h4>Cache</h4>
{props.cache.reduce((sum, entry) => {
return sum + (entry.val && entry.val.payload.data || 0);
}, 0).toLocaleString('de-DE')} bytes in cache
<SearchableList placeholder="cache url, LIVE vs CLEARED" items={cacheItems} open={false}>
<button onClick={this.loadCache}>refresh</button>
</SearchableList>
<h4>Connections</h4>
<SearchableList placeholder="duct, binding" items={connectionItems}>
<button onClick={this.loadConnections}>refresh</button>
@ -252,7 +300,7 @@ export class Eyre extends Component {
<br/>
<button onClick={this.loadAuthenticationState}>refresh</button>
<h3>Sessions</h3>
<SearchableList placeholder="identity" items={sessionItems}>
<SearchableList placeholder="identity" items={sessionItems} open={false}>
</SearchableList>
<h3>Outgoing eauth</h3>
<SearchableList placeholder="host" items={visitingItems}>

View File

@ -0,0 +1,310 @@
import { Component } from 'react';
import { showDirectoryPicker } from 'file-system-access';
import { msToDa } from '../lib/util';
import { store } from '../store';
export class Logs extends Component {
view: { oldest: number; newest: number; clicked: string; };
constructor(props) {
super(props);
this.state = {};
this.loadLogs = this.loadLogs.bind(this);
this.clearLogs = this.clearLogs.bind(this);
this.clickEvent = this.clickEvent.bind(this);
this.view = {
oldest: null,
newest: null,
clicked: null,
}
}
componentDidMount() {
//
}
componentDidUpdate(prevProps, prevState) {
const { props, state } = this;
//
console.log('updated component');
}
async loadLogs() {
const dir = await showDirectoryPicker();
if (dir.kind !== 'directory' || dir.name !== 'verb-logger') {
return alert('Not a real verb-logger put directory!');
}
for await (const [dude, logs] of dir.entries()) {
if (logs.kind !== 'directory') continue;
if (dude === '.DS_Store') continue;
let files = [];
for await (const [key, log] of logs.entries()) {
if (log.kind !== 'file') continue;
if (key.slice(-5) !== '.json') continue;
files.push({ key, log });
}
files = files.sort((a, b) => (a.key < b.key) ? -1 : 1);
for (const { key, log } of files) {
const start = parseInt(key.slice(0, -5));
const contents = JSON.parse(await (await log.getFile()).text());
const gill = contents.ship + '/' + contents.dude;
store.addLogs(gill, contents.from, contents.events);
}
}
}
clearLogs() {
store.clearLogs();
}
clickEvent(eventId) {
if (this.view.clicked === eventId)
this.view.clicked = null;
else
this.view.clicked = eventId;
this.setState({ view: this.view });
}
renderViewControls() {
const oldest = this.view.oldest || store.state.logsRange.oldest;
const newest = this.view.newest || store.state.logsRange.newest;
return (<div id="controls">
from {msToDa(oldest, true)}
<br/>
<input
type="range"
onChange={(e) => {
this.view.oldest = Number.parseInt(e.target.value);
this.setState({ view: this.view });
}} step="1"
min={store.state.logsRange.oldest}
max={store.state.logsRange.newest}
value={oldest}
/>
<br/>
<input
type="range"
onChange={(e) => {
const newest = Number.parseInt(e.target.value);
if (newest === store.state.logsRange.newest)
this.view.newest = null; // stick to latest
else
this.view.newest = newest;
this.setState({ view: this.view });
}} step="1"
min={store.state.logsRange.oldest}
max={store.state.logsRange.newest}
value={newest}
/>
<br/>
thru {msToDa(newest, true) + (this.view.newest ? '' : ' (live)')}
</div>);
}
renderEvent(gill, event, n) {
const oldest = this.view.oldest || store.state.logsRange.oldest;
const newest = this.view.newest || store.state.logsRange.newest;
const span = newest - oldest;
const id = `${gill}#${event.act}`;
const clicked = this.view.clicked === id;
let deets =
`
act: ${event.act}<br/>
now: ${msToDa(event.now, true)}<br/>
src: ${event.src}${event.sap}<br/>
`;
switch (event.kind) {
case 'on-poke':
deets = deets +
`
mark: %${event.deets.mark}<br/>
mug: 0x${event.deets.mug}
`;
break;
//
case 'on-watch':
case 'on-leave':
deets = deets + `path: ${event.deets}`;
break;
//
case 'on-agent':
deets = deets +
`
wire: ${event.deets.wire}<br/>
<u>${event.deets.sign}</u><br/>
`;
switch (event.deets.sign) {
case 'poke-ack':
case 'watch-ack':
deets = deets + (event.deets.deets ? 'ack' : 'nack');
break;
//
case 'fact':
deets = deets +
`
mark: %${event.deets.deets.mark}<br/>
mug: 0x${event.deets.deets.mug}
`;
break;
}
break;
}
deets = deets + `<br/><u>${event.effects.length} effects</u>`;
if (event.effects.length > 0) {
deets = deets + ':';
for (const effect of event.effects) {
deets = deets +
`
<details><summary>
${effect.kind}, ${effect.deets.wire || effect.deets.mark || ''}
</summary>
`;
switch (effect.kind) {
case 'poke':
deets = deets +
`
wire: ${effect.deets.wire}<br/>
gill: ${effect.deets.gill}<br/>
mark: %${effect.deets.mark}<br/>
mug: 0x${effect.deets.mug}
`;
break;
//
case 'watch':
deets = deets +
`
wire: ${effect.deets.wire}<br/>
gill: ${effect.deets.gill}<br/>
path: ${effect.deets.path}
`;
break;
//
case 'leave':
deets = deets +
`
wire: ${effect.deets.wire}<br/>
gill: ${effect.deets.gill}
`;
break;
//
case 'fact':
deets = deets +
`
paths: ${effect.deets.paths.join(', ')}<br/>
mark: %${effect.deets.mark}<br/>
mug: 0x${effect.deets.mug}
`;
break;
//
case 'kick':
deets = deets + `paths: ${effect.deets.paths.join(', ')}`;
break;
//
case 'arvo':
deets = deets +
`
wire: ${effect.deets.wire}<br/>
task: %${effect.deets.vane} %${effect.deets.task}
`;
break;
}
deets = deets + '</details>';
}
}
// if (event.kind === 'on-agent') {
// switch (event.deets.sign) {
// case 'fact':
// vent.style.borderColor = '#' + event.deets.deets.mug.slice(0, 6);
// break;
// //
// case 'poke-ack':
// case 'watch-ack':
// vent.style.borderColor = event.deets.deets ? 'green' : 'red';
// break;
// //
// case 'kick':
// vent.style.borderColor = 'purple';
// break;
// }
// }
const left = (((event.now - oldest) / span) * 98);
return (<div
className={'event' + (clicked ? ' focus' : '') + (left > 50 ? ' right' : '')}
onClick={() => this.clickEvent(id)}
style={{
left: left+'%',
top: ((n % 18) * 5)+'%',
}}
>
<div className={'details' + ((event.effects.length > 0) ? ' effects' : '')}
onClick={(e) => e.stopPropagation()}
dangerouslySetInnerHTML={{__html: deets}} />
</div>);
}
renderCauseRow(cause) {
return (<div className="cause">
<div className="legend">{cause.kind}</div>
{...cause.events}
</div>);
}
renderCauses(gill, logs) {
const oldest = this.view.oldest || store.state.logsRange.oldest;
const newest = this.view.newest || store.state.logsRange.newest;
console.log('oldest, newest', oldest, newest);
let causes = {};
for (const vent of logs) {
if (vent.now < oldest || vent.now > newest) continue;
const kind = vent.kind;
console.log('vent kind', kind);
const cause = causes[kind] || { kind: kind, events: [] };
const element = this.renderEvent(gill, vent, cause.events.length);
cause.events.push(element);
causes[kind] = cause;
}
return Object.values(causes).map(this.renderCauseRow);
}
renderLogs(logs) {
const children = [];
for (const [gill, agent] of Object.entries(logs)) {
children.push((<div className="agent">
<h3>{gill}</h3>
{this.renderCauses(gill, (agent as any).logs)}
</div>));
}
return children;
}
render() {
return (<>
<button onClick={this.loadLogs}>load logs</button>
{' '}
<button onClick={this.clearLogs}>clear logs</button>
<br/><br/>
{ Object.keys(store.state.logs).length === 0
? 'no logs yet. turn on verb+ for an app in the apps tab, or import log-viewer files.'
: [ this.renderViewControls(),
this.renderLogs(store.state.logs),
]
}
</>);
}
}

View File

@ -0,0 +1,35 @@
// import React from 'react'
// import ReactDOM from 'react-dom/client'
// import App from './App.tsx'
// import './index.css'
// ReactDOM.createRoot(document.getElementById('root')!).render(
// <React.StrictMode>
// <App />
// </React.StrictMode>,
// )
import React from 'react';
import ReactDOM from 'react-dom';
import { Root } from './js/components/root';
import { api } from './js/api';
import { store } from './js/store';
import { subscription } from "./js/subscription";
import './index.css';
api.setAuthTokens({
//@ts-ignore //TODO
ship: window.ship
});
console.log('new world!');
//@ts-ignore //TODO
window.urb = new window.channel();
subscription.start();
ReactDOM.render((
<Root />
), document.querySelectorAll("#root")[0]);

View File

@ -1,11 +0,0 @@
import React, { Component } from 'react';
import classnames from 'classnames';
import _ from 'lodash';
export default class DebugTile extends Component {
render() {
return null;
}
}
window.debugTile = DebugTile;

View File

@ -0,0 +1,24 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
//"strict": true,
//"noUnusedLocals": true,
//"noUnusedParameters": true,
//"noFallthroughCasesInSwitch": true
},
"include": ["src"],
}

View File

@ -0,0 +1,18 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
const rollupOptions = {
output: {
assetFileNames: '[name][extname]',
chunkFileNames: '[name].js',
entryFileNames: '[name].js',
hashCharacters: 'base36' as any
}
};
// https://vitejs.dev/config/
export default defineConfig({
base: '/~debug',
build: {rollupOptions},
plugins: [react()],
})

View File

@ -33,8 +33,7 @@
[~1111.1.1 0xdead.beef *roof]
:- ~[/use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud /init]
[%deal [~nec ~bud /] %pub %watch /foo]
:~ :- ~[/init] [%pass /sys/lag %a %heed ~bud]
:- ~[/init] [%pass /sys/era %j %public-keys (sy ~bud ~)]
:~ :- ~[/init] [%pass /sys/era %j %public-keys (sy ~bud ~)]
:- ~[/use/sub/0w1.d6Isf/out/~bud/pub/1/sub-foo/~bud /init]
[%pass /sys/way/~bud/pub %a %plea ~bud %g /ge/pub [%0 %s /foo]]
==
@ -84,8 +83,7 @@
[~1111.1.2 0xbeef.dead *roof]
:- ~[/bone/~nec/0/1 //unix]
[%plea ~nec %g /ge/pub [%0 %s /foo]]
:~ :- ~[/init] [%pass /sys/lag %a %heed ~nec]
:- ~[/init] [%pass /sys/era %j %public-keys (sy ~nec ~)]
:~ :- ~[/init] [%pass /sys/era %j %public-keys (sy ~nec ~)]
:- ~[/bone/~nec/0/1 //unix]
[%pass /sys/req/~nec/pub %g %deal [~nec ~bud /] %pub %watch /foo]
==
@ -172,18 +170,6 @@
~
==
:- t11 |. :- %|
:: start the clog and kick process; give clog to publisher gall
~? > dbug 'start the clog and kick process; give clog to publisher gall'
=^ t12 gall.bud
%: gall-check-take:v gall.bud
[~1111.1.4 0xbeef.dead *roof]
:+ /sys/lag ~[/init]
[%ames %clog ~nec]
:~ :- ~[/sys/req/~nec/pub /bone/~nec/0/1 //unix]
[%give %unto %kick ~]
==
==
:- t12 |. :- %|
:: gall gives %kick %boon to ames
~? > dbug 'gall gives %kick %boon to ames'
=^ t13 gall.bud