From 717c5a3ac99e8927ebe0173de3353511fc71a7d5 Mon Sep 17 00:00:00 2001 From: Maciej Hirsz <1096222+maciejhirsz@users.noreply.github.com> Date: Mon, 1 Oct 2018 14:10:54 +0200 Subject: [PATCH] Only update hardware stats when necessary (#73) --- packages/backend/src/Chain.ts | 1 + packages/backend/src/Feed.ts | 9 ++++++- packages/backend/src/MeanList.ts | 12 ++++++++- packages/backend/src/Node.ts | 26 +++++++++++++------ packages/common/src/feed.ts | 22 +++++++++++----- packages/common/src/index.ts | 2 +- packages/common/src/types.ts | 3 ++- packages/frontend/src/Connection.ts | 17 ++++++++++-- packages/frontend/src/components/Node/Row.tsx | 4 +-- packages/frontend/src/state.ts | 9 ++++++- 10 files changed, 81 insertions(+), 24 deletions(-) diff --git a/packages/backend/src/Chain.ts b/packages/backend/src/Chain.ts index c5c0bf2..d423636 100644 --- a/packages/backend/src/Chain.ts +++ b/packages/backend/src/Chain.ts @@ -44,6 +44,7 @@ export default class Chain { node.events.on('block', () => this.updateBlock(node)); node.events.on('stats', () => this.feeds.broadcast(Feed.stats(node))); + node.events.on('hardware', () => this.feeds.broadcast(Feed.hardware(node))); node.events.on('location', (location) => this.feeds.broadcast(Feed.locatedNode(node, location))); this.updateBlock(node); diff --git a/packages/backend/src/Feed.ts b/packages/backend/src/Feed.ts index 2c1069f..ffb053c 100644 --- a/packages/backend/src/Feed.ts +++ b/packages/backend/src/Feed.ts @@ -45,7 +45,7 @@ export default class Feed { public static addedNode(node: Node): FeedMessage.Message { return { action: Actions.AddedNode, - payload: [node.id, node.nodeDetails(), node.nodeStats(), node.blockDetails(), node.nodeLocation()] + payload: [node.id, node.nodeDetails(), node.nodeStats(), node.nodeHardware(), node.blockDetails(), node.nodeLocation()] }; } @@ -77,6 +77,13 @@ export default class Feed { }; } + public static hardware(node: Node): FeedMessage.Message { + return { + action: Actions.NodeHardware, + payload: [node.id, node.nodeHardware()] + }; + } + public static timeSync(): FeedMessage.Message { return { action: Actions.TimeSync, diff --git a/packages/backend/src/MeanList.ts b/packages/backend/src/MeanList.ts index 3a8136c..dca5332 100644 --- a/packages/backend/src/MeanList.ts +++ b/packages/backend/src/MeanList.ts @@ -7,12 +7,22 @@ export class MeanList { private means = Array(20).fill(0 as T); private ticksPerMean = 1; - public push(val: T) { + /** + * Push a new value, returns true if a new mean value was produced + * + * @param {T} value + * + * @return {boolean} + */ + public push(val: T): boolean { this.period[this.periodIndex++] = val; if (this.periodIndex === this.ticksPerMean) { this.pushMean(); + return true; } + + return false; } public get(): Array { diff --git a/packages/backend/src/Node.ts b/packages/backend/src/Node.ts index ac5881e..f5188b2 100644 --- a/packages/backend/src/Node.ts +++ b/packages/backend/src/Node.ts @@ -179,7 +179,11 @@ export default class Node { } public nodeStats(): Types.NodeStats { - return [this.peers, this.txcount, this.memory.get(), this.cpu.get(), this.chartstamps.get()]; + return [this.peers, this.txcount]; + } + + public nodeHardware(): Types.NodeHardware { + return [this.memory.get(), this.cpu.get(), this.chartstamps.get()]; } public blockDetails(): Types.BlockDetails { @@ -231,16 +235,22 @@ export default class Node { private onSystemInterval(message: SystemInterval) { const { peers, txcount, cpu, memory } = message; - this.peers = peers; - this.txcount = txcount; + if (this.peers !== peers || this.txcount !== txcount) { + this.peers = peers; + this.txcount = txcount; - if (cpu != null && memory != null) { - this.cpu.push(cpu); - this.memory.push(memory); - this.chartstamps.push(timestamp()); + this.events.emit('stats'); } - this.events.emit('stats'); + if (cpu != null && memory != null) { + const cpuChange = this.cpu.push(cpu); + const memChange = this.memory.push(memory); + const stampChange = this.chartstamps.push(timestamp()); + + if (cpuChange || memChange || stampChange) { + this.events.emit('hardware'); + } + } } private updateLatency(now: Types.Timestamp) { diff --git a/packages/common/src/feed.ts b/packages/common/src/feed.ts index 93f586c..b45f1e8 100644 --- a/packages/common/src/feed.ts +++ b/packages/common/src/feed.ts @@ -10,6 +10,7 @@ import { NodeCount, NodeDetails, NodeStats, + NodeHardware, NodeLocation, BlockNumber, BlockDetails, @@ -26,12 +27,13 @@ export const Actions = { LocatedNode : 0x04 as 0x04, ImportedBlock : 0x05 as 0x05, NodeStats : 0x06 as 0x06, - TimeSync : 0x07 as 0x07, - AddedChain : 0x08 as 0x08, - RemovedChain : 0x09 as 0x09, - SubscribedTo : 0x0A as 0x0A, - UnsubscribedFrom : 0x0B as 0x0B, - Pong : 0x0C as 0x0C, + NodeHardware : 0x07 as 0x07, + TimeSync : 0x08 as 0x08, + AddedChain : 0x09 as 0x09, + RemovedChain : 0x0A as 0x0A, + SubscribedTo : 0x0B as 0x0B, + UnsubscribedFrom : 0x0C as 0x0C, + Pong : 0x0D as 0x0D, }; export type Action = typeof Actions[keyof typeof Actions]; @@ -54,7 +56,7 @@ export namespace Variants { export interface AddedNodeMessage extends MessageBase { action: typeof Actions.AddedNode; - payload: [NodeId, NodeDetails, NodeStats, BlockDetails, Maybe]; + payload: [NodeId, NodeDetails, NodeStats, NodeHardware, BlockDetails, Maybe]; } export interface RemovedNodeMessage extends MessageBase { @@ -77,6 +79,11 @@ export namespace Variants { payload: [NodeId, NodeStats]; } + export interface NodeHardwareMessage extends MessageBase { + action: typeof Actions.NodeHardware; + payload: [NodeId, NodeHardware]; + } + export interface TimeSyncMessage extends MessageBase { action: typeof Actions.TimeSync; payload: Timestamp; @@ -116,6 +123,7 @@ export type Message = | Variants.LocatedNodeMessage | Variants.ImportedBlockMessage | Variants.NodeStatsMessage + | Variants.NodeHardwareMessage | Variants.TimeSyncMessage | Variants.AddedChainMessage | Variants.RemovedChainMessage diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts index a7d0330..8cef054 100644 --- a/packages/common/src/index.ts +++ b/packages/common/src/index.ts @@ -8,4 +8,4 @@ import * as FeedMessage from './feed'; export { Types, FeedMessage }; // Increment this if breaking changes were made to types in `feed.ts` -export const VERSION: Types.FeedVersion = 18 as Types.FeedVersion; +export const VERSION: Types.FeedVersion = 19 as Types.FeedVersion; diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index dc089eb..784a2b4 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -25,5 +25,6 @@ export type CPUUse = Opaque; export type BlockDetails = [BlockNumber, BlockHash, Milliseconds, Timestamp, Maybe]; export type NodeDetails = [NodeName, NodeImplementation, NodeVersion, Maybe
]; -export type NodeStats = [PeerCount, TransactionCount, Array, Array, Array]; +export type NodeStats = [PeerCount, TransactionCount]; +export type NodeHardware = [Array, Array, Array]; export type NodeLocation = [Latitude, Longitude, City]; diff --git a/packages/frontend/src/Connection.ts b/packages/frontend/src/Connection.ts index 6002147..8c64db1 100644 --- a/packages/frontend/src/Connection.ts +++ b/packages/frontend/src/Connection.ts @@ -174,9 +174,9 @@ export class Connection { } case Actions.AddedNode: { - const [id, nodeDetails, nodeStats, blockDetails, location] = message.payload; + const [id, nodeDetails, nodeStats, nodeHardware, blockDetails, location] = message.payload; const pinned = this.pins.has(nodeDetails[0]); - const node = new Node(pinned, id, nodeDetails, nodeStats, blockDetails, location); + const node = new Node(pinned, id, nodeDetails, nodeStats, nodeHardware, blockDetails, location); nodes.set(id, node); sortedInsert(node, sortedNodes, Node.compare); @@ -251,6 +251,19 @@ export class Connection { break; } + case Actions.NodeHardware: { + const [id, nodeHardware] = message.payload; + const node = nodes.get(id); + + if (!node) { + return; + } + + node.updateHardware(nodeHardware); + + break; + } + case Actions.TimeSync: { this.state = this.update({ timeDiff: (timestamp() - message.payload) as Types.Milliseconds diff --git a/packages/frontend/src/components/Node/Row.tsx b/packages/frontend/src/components/Node/Row.tsx index efd9417..576f229 100644 --- a/packages/frontend/src/components/Node/Row.tsx +++ b/packages/frontend/src/components/Node/Row.tsx @@ -58,8 +58,8 @@ function Truncate(props: { text: string, position?: 'left' | 'right' | 'center' function formatStamp(stamp: Types.Timestamp): string { const passed = (timestamp() - stamp) / 1000 | 0; - const hours = Math.round(passed / 3600); - const minutes = Math.round((passed % 3600) / 60); + const hours = passed / 3600 | 0; + const minutes = (passed % 3600) / 60 | 0; const seconds = (passed % 60) | 0; return hours ? `${hours}h ago` diff --git a/packages/frontend/src/state.ts b/packages/frontend/src/state.ts index 91d4507..c0f92ba 100644 --- a/packages/frontend/src/state.ts +++ b/packages/frontend/src/state.ts @@ -46,6 +46,7 @@ export class Node { id: Types.NodeId, nodeDetails: Types.NodeDetails, nodeStats: Types.NodeStats, + nodeHardware: Types.NodeHardware, blockDetails: Types.BlockDetails, location: Maybe ) { @@ -60,6 +61,7 @@ export class Node { this.validator = validator; this.updateStats(nodeStats); + this.updateHardware(nodeHardware); this.updateBlock(blockDetails); if (location) { @@ -68,10 +70,15 @@ export class Node { } public updateStats(stats: Types.NodeStats) { - const [peers, txs, mem, cpu, chartstamps] = stats; + const [peers, txs] = stats; this.peers = peers; this.txs = txs; + } + + public updateHardware(hardware: Types.NodeHardware) { + const [mem, cpu, chartstamps] = hardware; + this.mem = mem; this.cpu = cpu; this.chartstamps = chartstamps;