Skip to content
Snippets Groups Projects
Commit 92dd588e authored by Nicolas Pope's avatar Nicolas Pope
Browse files

Generate statistics every second

parent 9a672e7b
No related branches found
No related tags found
1 merge request!2Generate statistics every second
Pipeline #57409 canceled
......@@ -30,6 +30,18 @@ export interface Peer extends Emitter {}
export type RPCMethod = (...args: unknown[]) => unknown;
interface IStatistics {
txTotal: number;
rxTotal: number;
txBytes: number;
rxBytes: number;
txRate: number;
rxRate: number;
txRequested: number;
txRatio: number; // Requested over sent, should be close to 1
duration: number;
};
/**
* Wrap a web socket with a MsgPack RCP protocol that works with our C++ version.
* @param {websocket} ws Websocket object
......@@ -45,7 +57,6 @@ export class Peer {
callbacks = {};
cbid = 0;
server = false;
sendCount = 0;
latency = 0;
......@@ -54,12 +65,25 @@ export class Peer {
master = false;
txBytes = 0;
txRequested = 0;
rxBytes = 0;
lastStatsCall = Date.now();
lastStats = null;
lastStats: IStatistics = {
txTotal: 0,
rxTotal: 0,
txBytes: 0,
rxBytes: 0,
txRate: 0,
rxRate: 0,
txRequested: 0,
txRatio: 0,
duration: 0,
};
static uuid: string;
static peers: Map<string, Peer> = new Map();
constructor(ws?: WebSocketConnection, server = false) {
this.sock = ws;
this.server = server;
......@@ -71,7 +95,7 @@ export class Peer {
raw = raw.data;
}
this.rxBytes += raw.length || raw.byteLength;
this.rxBytes += raw.length || raw.byteLength || 0;
const msg = decode(raw);
// console.log('MSG', msg)
if (this.status === kConnecting) {
......@@ -97,6 +121,7 @@ export class Peer {
const close = () => {
this.emit("disconnect", this);
this.status = kDisconnected;
Peer.removePeer(this);
}
const error = (e) => {
......@@ -129,28 +154,39 @@ export class Peer {
}
getStatistics() {
return this.lastStats;
}
updateStatistics() {
const time = Date.now();
if (time - this.lastStatsCall > 5000 || !this.lastStats) {
this.lastStats = [time - this.lastStatsCall, this.rxBytes, 0];
this.rxBytes = 0;
const duration = time - this.lastStatsCall;
if (duration < 10) return;
this.lastStats = {
txTotal: this.lastStats.txTotal + this.txBytes,
rxTotal: this.lastStats.rxTotal + this.rxBytes,
txBytes: this.txBytes,
rxBytes: this.rxBytes,
txRate: this.txBytes / duration,
rxRate: this.rxBytes / duration,
txRequested: this.txRequested,
txRatio: (this.txBytes > 0) ? this.txRequested / this.txBytes : 0.0,
duration,
};
this.txBytes = 0;
this.rxBytes = 0;
this.txRequested = 0;
this.lastStatsCall = time;
}
return this.lastStats;
}
sendHandshake() {
this.send("__handshake__", kMagic, kVersion, [my_uuid]);
}
isBuffering(): boolean {
return this.sendCount > 0;
}
private _send(msg: Buffer | ReturnType<typeof encode>) {
++this.sendCount;
const bytes = msg.length;
this.txRequested += bytes;
this.sock.send(msg, () => {
--this.sendCount;
this.txBytes += bytes;
});
}
......@@ -159,6 +195,7 @@ export class Peer {
this.status = kConnected;
this.id = id[0];
this.string_id = id[0].toString('hex');
Peer.addPeer(this);
if (!this.server) {
this.sendHandshake();
}
......@@ -319,6 +356,27 @@ export class Peer {
getUuid(): string {
return uuid;
}
static interval?: NodeJS.Timer;
static addPeer(p: Peer) {
Peer.peers.set(p.string_id, p);
if (Peer.peers.size === 1) {
Peer.interval = setInterval(() => {
for (const [id, peer] of Peer.peers) {
peer.updateStatistics();
}
}, 1000);
}
}
static removePeer(p: Peer) {
Peer.peers.delete(p.string_id);
if (Peer.peers.size === 0 && Peer.interval) {
clearInterval(Peer.interval);
Peer.interval = undefined;
}
}
}
ee(Peer.prototype);
......
import {Peer} from '../src/Peer';
import WebSocket from 'ws';
function wait(ms: number) {
return new Promise<void>((resolve) => setTimeout(resolve, ms));
}
describe("Peer class", () => {
let clientPeer: Peer;
let serverPeer: Peer;
......@@ -91,4 +95,22 @@ describe("Peer class", () => {
expect.assertions(3);
});
it("can generate statistics", async () => {
expect(clientPeer).toBeTruthy();
expect(serverPeer).toBeTruthy();
await new Promise((resolve) => {
serverPeer.bind("test_rpc", (value) => {
expect(value).toBe(50);
resolve(true);
});
clientPeer.send("test_rpc", 50);
});
await wait(2000);
expect(serverPeer.getStatistics().txTotal).toBeGreaterThan(0);
});
});
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment