Relay stats
This commit is contained in:
parent
357937b403
commit
6f3a0e83ce
@ -1,10 +1,24 @@
|
||||
.relay {
|
||||
margin-bottom: 10px;
|
||||
margin-top: 10px;
|
||||
background-color: var(--gray-secondary);
|
||||
border-radius: 5px;
|
||||
text-align: start;
|
||||
display: grid;
|
||||
grid-template-columns: min-content auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.relay > div {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.relay > div:first-child {
|
||||
}
|
||||
|
||||
.relay-extra {
|
||||
padding: 5px;
|
||||
margin: 0 5px;
|
||||
background-color: var(--gray-tertiary);
|
||||
border-radius: 0 0 5px 5px;
|
||||
white-space: nowrap;
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
import "./Relay.css"
|
||||
|
||||
import { faPlug, faTrash, faSquareCheck, faSquareXmark } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faPlug, faTrash, faSquareCheck, faSquareXmark, faWifi, faUpload, faDownload, faPlugCircleXmark, faEllipsisVertical } from "@fortawesome/free-solid-svg-icons";
|
||||
import useRelayState from "../feed/RelayState";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useMemo } from "react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { removeRelay, setRelays } from "../state/Login";
|
||||
|
||||
@ -13,6 +13,7 @@ export default function Relay(props) {
|
||||
const relaySettings = useSelector(s => s.login.relays[props.addr]);
|
||||
const state = useRelayState(props.addr);
|
||||
const name = useMemo(() => new URL(props.addr).host, [props.addr]);
|
||||
const [showExtra, setShowExtra] = useState(false);
|
||||
|
||||
function configure(o) {
|
||||
dispatch(setRelays({
|
||||
@ -20,31 +21,59 @@ export default function Relay(props) {
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
let latency = parseInt(state?.avgLatency ?? 0);
|
||||
return (
|
||||
<>
|
||||
<div className="flex relay w-max">
|
||||
<div>
|
||||
<FontAwesomeIcon icon={faPlug} color={state?.connected ? "var(--success)" : "var(--error)"} />
|
||||
<div className={`relay w-max`}>
|
||||
<div className={`flex ${state?.connected ? "bg-success" : "bg-error"}`}>
|
||||
<FontAwesomeIcon icon={faPlug} />
|
||||
</div>
|
||||
<div className="f-grow f-col">
|
||||
<b>{name}</b>
|
||||
<div>
|
||||
Write
|
||||
<span className="pill" onClick={() => configure({ write: !relaySettings.write, read: relaySettings.read })}>
|
||||
<FontAwesomeIcon icon={relaySettings.write ? faSquareCheck : faSquareXmark} />
|
||||
</span>
|
||||
Read
|
||||
<span className="pill" onClick={() => configure({ write: relaySettings.write, read: !relaySettings.read })}>
|
||||
<FontAwesomeIcon icon={relaySettings.read ? faSquareCheck : faSquareXmark} />
|
||||
</span>
|
||||
<div className="flex mb10">
|
||||
<b className="f-2">{name}</b>
|
||||
<div className="f-1">
|
||||
Write
|
||||
<span className="pill" onClick={() => configure({ write: !relaySettings.write, read: relaySettings.read })}>
|
||||
<FontAwesomeIcon icon={relaySettings.write ? faSquareCheck : faSquareXmark} />
|
||||
</span>
|
||||
</div>
|
||||
<div className="f-1">
|
||||
Read
|
||||
<span className="pill" onClick={() => configure({ write: relaySettings.write, read: !relaySettings.read })}>
|
||||
<FontAwesomeIcon icon={relaySettings.read ? faSquareCheck : faSquareXmark} />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex">
|
||||
<div className="f-grow">
|
||||
<FontAwesomeIcon icon={faWifi} /> {latency > 2000 ? `${(latency / 1000).toFixed(0)} secs` : `${latency.toLocaleString()} ms`}
|
||||
|
||||
<FontAwesomeIcon icon={faPlugCircleXmark} /> {state?.disconnects}
|
||||
</div>
|
||||
<div>
|
||||
<span className="pill" onClick={() => setShowExtra(s => !s)}>
|
||||
<FontAwesomeIcon icon={faEllipsisVertical} />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<span className="pill">
|
||||
<FontAwesomeIcon icon={faTrash} onClick={() => dispatch(removeRelay(props.addr))} />
|
||||
</div>
|
||||
{showExtra ? <div className="flex relay-extra w-max">
|
||||
<div className="f-1">
|
||||
<FontAwesomeIcon icon={faUpload} /> {state?.events.send}
|
||||
</div>
|
||||
<div className="f-1">
|
||||
<FontAwesomeIcon icon={faDownload} /> {state?.events.received}
|
||||
</div>
|
||||
|
||||
<div className="f-1">
|
||||
Delete
|
||||
<span className="pill" onClick={() => dispatch(removeRelay(props.addr))}>
|
||||
<FontAwesomeIcon icon={faTrash} />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div> : null}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -133,6 +133,10 @@ textarea:placeholder {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.f-2 {
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
.f-grow {
|
||||
flex-grow: 1;
|
||||
}
|
||||
@ -271,6 +275,14 @@ body.scroll-lock {
|
||||
color: var(--error);
|
||||
}
|
||||
|
||||
.bg-error {
|
||||
background-color: var(--error);
|
||||
}
|
||||
|
||||
.bg-success {
|
||||
background-color: var(--success);
|
||||
}
|
||||
|
||||
.root-tabs {
|
||||
padding: 0;
|
||||
align-items: center;
|
||||
|
@ -12,6 +12,7 @@ export class ConnectionStats {
|
||||
this.SubsTimeout = 0;
|
||||
this.EventsReceived = 0;
|
||||
this.EventsSent = 0;
|
||||
this.Disconnects = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,7 +29,13 @@ export default class Connection {
|
||||
this.StateHooks = {};
|
||||
this.HasStateChange = true;
|
||||
this.CurrentState = {
|
||||
connected: false
|
||||
connected: false,
|
||||
disconnects: 0,
|
||||
avgLatency: 0,
|
||||
events: {
|
||||
received: 0,
|
||||
send: 0
|
||||
}
|
||||
};
|
||||
this.LastState = Object.freeze({ ...this.CurrentState });
|
||||
this.IsClosed = false;
|
||||
@ -47,7 +54,7 @@ export default class Connection {
|
||||
|
||||
Close() {
|
||||
this.IsClosed = true;
|
||||
if(this.ReconnectTimer !== null) {
|
||||
if (this.ReconnectTimer !== null) {
|
||||
clearTimeout(this.ReconnectTimer);
|
||||
this.ReconnectTimer = null;
|
||||
}
|
||||
@ -74,6 +81,7 @@ export default class Connection {
|
||||
this.ReconnectTimer = setTimeout(() => {
|
||||
this.Connect();
|
||||
}, this.ConnectTimeout);
|
||||
this.Stats.Disconnects++;
|
||||
} else {
|
||||
console.log(`[${this.Address}] Closed!`);
|
||||
this.ReconnectTimer = null;
|
||||
@ -88,6 +96,8 @@ export default class Connection {
|
||||
switch (tag) {
|
||||
case "EVENT": {
|
||||
this._OnEvent(msg[1], msg[2]);
|
||||
this.Stats.EventsReceived++;
|
||||
this._UpdateState();
|
||||
break;
|
||||
}
|
||||
case "EOSE": {
|
||||
@ -96,7 +106,7 @@ export default class Connection {
|
||||
}
|
||||
case "OK": {
|
||||
// feedback to broadcast call
|
||||
console.debug("OK: ", msg[1]);
|
||||
console.debug("OK: ", msg);
|
||||
break;
|
||||
}
|
||||
case "NOTICE": {
|
||||
@ -126,6 +136,8 @@ export default class Connection {
|
||||
}
|
||||
let req = ["EVENT", e.ToObject()];
|
||||
this._SendJson(req);
|
||||
this.Stats.EventsSent++;
|
||||
this._UpdateState();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -199,6 +211,11 @@ export default class Connection {
|
||||
|
||||
_UpdateState() {
|
||||
this.CurrentState.connected = this.Socket?.readyState === WebSocket.OPEN;
|
||||
this.CurrentState.events.received = this.Stats.EventsReceived;
|
||||
this.CurrentState.events.send = this.Stats.EventsSent;
|
||||
this.CurrentState.avgLatency = this.Stats.Latency.length > 0 ? (this.Stats.Latency.reduce((acc, v) => acc + v, 0) / this.Stats.Latency.length) : 0;
|
||||
this.CurrentState.disconnects = this.Stats.Disconnects;
|
||||
this.Stats.Latency = this.Stats.Latency.slice(this.Stats.Latency.length - 20); // trim
|
||||
this.HasStateChange = true;
|
||||
this._NotifyState();
|
||||
}
|
||||
@ -239,9 +256,10 @@ export default class Connection {
|
||||
console.warn(`[${this.Address}][${subId}] Slow response time ${(responseTime / 1000).toFixed(1)} seconds`);
|
||||
}
|
||||
sub.OnEnd(this);
|
||||
this.Stats.Latency.push(responseTime);
|
||||
this._UpdateState();
|
||||
} else {
|
||||
// console.warn(`No subscription for end! ${subId}`);
|
||||
// ignored for now, track as "dropped event" with connection stats
|
||||
console.warn(`No subscription for end! ${subId}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user