dbug: support more eyre scries

This commit is contained in:
Fang 2020-05-22 23:57:41 +02:00
parent 52ef23ccca
commit 309d30a0c8
No known key found for this signature in database
GPG Key ID: EB035760C1BBA972
6 changed files with 287 additions and 20 deletions

View File

@ -309,12 +309,89 @@
|= [binding =duct =action]
%- pairs
:~ 'location'^s+(cat 3 (fall site '*') (spat path))
'action'^(render-action:v-eyre action)
==
::
:: /eyre/connections.json
::
[%eyre %connections ~]
%- some
:- %a
%+ turn ~(tap by connections:v-eyre)
|= [=duct outstanding-connection:eyre]
%- pairs
:~ 'duct'^a+(turn duct path)
'action'^(render-action:v-eyre action)
::
:- 'action'
:- %s
?+ -.action -.action
%gen :((cury cat 3) '+' (spat [desk path]:generator.action))
%app (cat 3 ':' app.action)
:- 'request'
%- pairs
=, inbound-request
:~ 'authenticated'^b+authenticated
'secure'^b+secure
'source'^s+(scot %if +.address)
:: ?- -.address
:: %ipv4 %if
:: %ipv6 %is
:: ==
==
::
:- 'response'
%- pairs
:~ 'sent'^(numb bytes-sent)
::
:- 'header'
?~ response-header ~
=, u.response-header
%- pairs
:~ 'status-code'^(numb status-code)
::
:- 'headers'
:- %a
%+ turn headers
|=([k=@t v=@t] s+:((cury cat 3) k ': ' v))
==
==
==
::
:: /eyre/authentication.json
::
[%eyre %authentication ~]
%- some
:- %a
%+ turn
%+ sort ~(tap by sessions:auth-state:v-eyre)
|= [[@uv a=@da] [@uv b=@da]]
(gth a b)
|= [cookie=@uv session:eyre]
%- pairs
:~ 'cookie'^s+(end 3 4 (rsh 3 2 (scot %x (shax cookie))))
'expiry'^(time expiry-time)
==
::
:: /eyre/channels.json
::
[%eyre %channels ~]
%- some
:- %a
=+ channel-state:v-eyre
%+ turn ~(tap by session)
|= [key=@t channel:eyre]
%- pairs
:~ 'session'^s+key
'connected'^b+!-.state
'expiry'^?-(-.state %& (time date.p.state), %| ~)
'next-id'^(numb next-id)
'unacked'^a+(turn (sort (turn ~(tap in events) head) dor) numb)
::
:- 'subscriptions'
:- %a
%+ turn ~(tap by subscriptions)
|= [=wire [=^ship app=term =^path *]]
%- pairs
:~ 'wire'^(^path wire)
'ship'^(^ship ship)
'app'^s+app
'path'^(^path path)
==
==
==
@ -784,10 +861,28 @@
:: eyre
::
++ v-eyre
=, eyre
|%
++ bindings
=, eyre
(scry ,(list [=binding =duct =action]) %e %bindings ~)
::
++ connections
(scry ,(map duct outstanding-connection) %e %connections ~)
::
++ auth-state
(scry authentication-state %e %authentication-state ~)
::
++ channel-state
(scry ^channel-state %e %channel-state ~)
::
++ render-action
|= =action
^- json
:- %s
?+ -.action -.action
%gen :((cury cat 3) '+' (spat [desk path]:generator.action))
%app (cat 3 ':' app.action)
==
--
::
:: helpers

View File

@ -201,6 +201,27 @@ class UrbitApi {
);
}
getConnections() {
this.getJson('/eyre/connections',
this.wrapLocal('eyreConnections'),
this.showStatus('error fetching eyre connections')
);
}
getAuthenticationState() {
this.getJson('/eyre/authentication',
this.wrapLocal('eyreAuthentication'),
this.showStatus('error fetching eyre authentication state')
);
}
getChannels() {
this.getJson('/eyre/channels',
this.wrapLocal('eyreChannels'),
this.showStatus('error fetching eyre channels')
);
}
// local
sidebarToggle() {

View File

@ -98,7 +98,13 @@ export class Root extends Component {
render={(props) => {
return (
<Skeleton status={state.status} selected="eyre">
<Eyre bindings={state.bindings} {...props}/>
<Eyre
bindings={state.bindings}
connections={state.connections}
authentication={state.authentication}
channels={state.channels}
{...props}
/>
</Skeleton>
);
}}

View File

@ -23,6 +23,9 @@ export class LocalReducer {
this.clayCommits(data, state);
//
this.eyreBindings(data, state);
this.eyreConnections(data, state);
this.eyreAuthentication(data, state);
this.eyreChannels(data, state);
}
}
@ -152,4 +155,25 @@ export class LocalReducer {
state.bindings = data;
}
}
eyreConnections(obj, state) {
const data = _.get(obj, 'eyreConnections', false);
if (data) {
state.connections = data;
}
}
eyreAuthentication(obj, state) {
const data = _.get(obj, 'eyreAuthentication', false);
if (data) {
state.authentication = data;
}
}
eyreChannels(obj, state) {
const data = _.get(obj, 'eyreChannels', false);
if (data) {
state.channels = data;
}
}
}

View File

@ -11,6 +11,9 @@ class Store {
timers: [],
commits: [],
bindings: [],
connections: [],
authentication: [],
channels: [],
sidebarShown: true
};

View File

@ -3,6 +3,7 @@ import { Route, Link } from 'react-router-dom';
import { msToDa, renderDuct } from '../lib/util';
import urbitOb from 'urbit-ob';
import { SearchableList } from '../components/searchable-list';
import { Summary } from '../components/summary';
export class Eyre extends Component {
@ -11,13 +12,17 @@ export class Eyre extends Component {
this.state = {};
this.loadBindings = this.loadBindings.bind(this);
this.loadConnections = this.loadConnections.bind(this);
this.loadAuthenticationState = this.loadAuthenticationState.bind(this);
this.loadChannels = this.loadChannels.bind(this);
}
componentDidMount() {
const { bindings } = this.props;
if (bindings.length === 0) {
this.loadBindings();
}
const { props } = this;
if (props.bindings.length === 0) this.loadBindings();
if (props.connections.length == 0) this.loadConnections();
if (props.authentication.length == 0) this.loadAuthenticationState();
if (props.channels.length == 0) this.loadChannels();
}
componentDidUpdate(prevProps, prevState) {
@ -29,12 +34,23 @@ export class Eyre extends Component {
api.getBindings();
}
loadConnections() {
api.getConnections();
}
loadAuthenticationState() {
api.getAuthenticationState();
}
loadChannels() {
api.getChannels();
}
//TODO use classes for styling?
render() {
const { props, state } = this;
const items = props.bindings.map(binding => {
const bindingItems = props.bindings.map(binding => {
return {key: binding.location + ' ' + binding.action, jsx: (<div class="flex">
<div class="flex-auto" style={{maxWidth: '50%'}}>
{binding.location}
@ -45,12 +61,114 @@ export class Eyre extends Component {
</div>)};
});
return (
<table><tbody>
<SearchableList placeholder="binding" items={items}>
<button onClick={this.loadBindings}>refresh</button>
</SearchableList>
</tbody></table>
);
const connectionItems = props.connections.map(c => {
return {key: c.duct + ' ' + c.action, jsx: (
<table style={{borderBottom: '1px solid black'}}><tbody>
<tr>
<td class="inter">duct</td>
<td>{c.duct}</td>
</tr>
<tr>
<td class="inter">binding</td>
<td>{c.action}</td>
</tr>
<tr>
<td class="inter">request</td>
<td>
from {c.request.source},
{c.request.authenticated ? ' ' : ' un'}authenticated and
{c.request.secure ? ' ' : ' in'}secure
</td>
</tr>
<tr>
<td class="inter">response</td>
<td>
sent {c.response.sent} bytes.<br/>
{!c.response.header ? null : <>
status {c.response.header['status-code']}<br/>
{c.response.header.headers.reduce((a, b) => a + b + ', ', '')}
</>}
</td>
</tr>
</tbody></table>
)};
});
const channelItems = props.channels.map(c => {
const summary = (<>
{c.session}
<table style={{borderBottom: '1px solid black'}}><tbody>
<tr>
<td class="inter">connected?</td>
<td>{c.connected
? 'connected'
: 'disconnected, expires ' + msToDa(c.expiry)
}</td>
</tr>
<tr>
<td class="inter">next-id</td>
<td>{c['next-id']}</td>
</tr>
<tr>
<td class="inter">unacked</td>
<td>{c.unacked.reduce((a, b) => a + b + ', ', '')}</td>
</tr>
</tbody></table>
</>);
const subscriptionItems = c.subscriptions.map(s => {
//NOTE jsx sorta copied from /components/subscriptions
return {key: `${s.wire} ${s.app} ${s.ship} ${s.path}`, jsx: (
<div class="flex">
<div class="flex-auto" style={{maxWidth: '35%'}}>
{s.wire}
</div>
<div class="flex-auto" style={{maxWidth: '15%'}}>
~{s.ship}
</div>
<div class="flex-auto" style={{maxWidth: '15%'}}>
{s.app}
</div>
<div class="flex-auto" style={{maxWidth: '35%'}}>
{s.path}
</div>
</div>
)};
});
return {key: c.session, jsx: (
<Summary summary={summary} details={(
<SearchableList
placeholder="wire, app, ship, path"
items={subscriptionItems}
/>
)} />
)};
});
const sessionItems = props.authentication.map(s => {
return (<div>
{`${s.cookie} expires ${msToDa(s.expiry)}`}
</div>);
});
return (<>
<h4>Bindings</h4>
<SearchableList placeholder="binding" items={bindingItems}>
<button onClick={this.loadBindings}>refresh</button>
</SearchableList>
<h4>Connections</h4>
<SearchableList placeholder="duct, binding" items={connectionItems}>
<button onClick={this.loadConnections}>refresh</button>
</SearchableList>
<h4>Channels</h4>
<SearchableList placeholder="session id" items={channelItems}>
<button onClick={this.loadChannels}>refresh</button>
</SearchableList>
<h4>Cookies</h4>
<button onClick={this.loadAuthenticationState}>refresh</button>
{sessionItems}
</>);
}
}