Render individual node changes on demand (#76)

This commit is contained in:
Maciej Hirsz
2018-10-05 18:21:43 +02:00
committed by GitHub
parent 784c112af3
commit d299e2103a
3 changed files with 92 additions and 22 deletions
+34 -21
View File
@@ -85,7 +85,10 @@ export class Connection {
const { nodes, chains } = this.state;
let { sortedNodes } = this.state;
messages: for (const message of messages) {
// TODO: boolean flags are code smell, find a cleaner way to do this
let dirty = false;
for (const message of messages) {
switch (message.action) {
case Actions.FeedVersion: {
if (message.payload !== VERSION) {
@@ -98,17 +101,17 @@ export class Connection {
return;
}
continue messages;
break;
}
case Actions.BestBlock: {
const [best, blockTimestamp, blockAverage] = message.payload;
nodes.forEach((node) => node.propagationTime = null);
nodes.forEach((node) => node.newBestBlock());
this.state = this.update({ best, blockTimestamp, blockAverage });
continue messages;
break;
}
case Actions.AddedNode: {
@@ -124,6 +127,8 @@ export class Connection {
sortedNodes = Array.from(nodes.values()).sort(Node.compare);
}
dirty = true;
break;
}
@@ -140,11 +145,11 @@ export class Connection {
console.error('Node count in sorted array is wrong!');
sortedNodes = Array.from(nodes.values()).sort(Node.compare);
}
break;
}
continue messages;
dirty = true;
break;
}
case Actions.LocatedNode: {
@@ -152,12 +157,10 @@ export class Connection {
const node = nodes.get(id);
if (!node) {
continue messages;
break;
}
node.lat = lat;
node.lon = lon;
node.city = city;
node.updateLocation([lat, lon, city]);
break;
}
@@ -167,12 +170,14 @@ export class Connection {
const node = nodes.get(id);
if (!node) {
continue messages;
break;
}
node.updateBlock(blockDetails);
sortedNodes = sortedNodes.sort(Node.compare);
dirty = true;
break;
}
@@ -181,7 +186,7 @@ export class Connection {
const node = nodes.get(id);
if (!node) {
return;
break;
}
node.updateStats(nodeStats);
@@ -207,13 +212,15 @@ export class Connection {
timeDiff: (timestamp() - message.payload) as Types.Milliseconds
});
continue messages;
break;
}
case Actions.AddedChain: {
const [label, nodeCount] = message.payload;
chains.set(label, nodeCount);
dirty = true;
break;
}
@@ -224,10 +231,10 @@ export class Connection {
nodes.clear();
sortedNodes = [];
this.state = this.update({ subscribed: null, nodes, chains, sortedNodes });
continue messages;
}
dirty = true;
break;
}
@@ -237,7 +244,9 @@ export class Connection {
this.state = this.update({ subscribed: message.payload, nodes, sortedNodes });
continue messages;
dirty = true;
break;
}
case Actions.UnsubscribedFrom: {
@@ -247,22 +256,26 @@ export class Connection {
this.state = this.update({ subscribed: null, nodes, sortedNodes });
}
continue messages;
dirty = true;
break;
}
case Actions.Pong: {
this.pong(Number(message.payload));
continue messages;
break;
}
default: {
continue messages;
break;
}
}
}
this.state = this.update({ nodes, chains, sortedNodes });
if (dirty) {
this.state = this.update({ nodes, chains, sortedNodes });
}
this.autoSubscribe();
}
+27 -1
View File
@@ -33,6 +33,10 @@ interface RowProps {
pins: PersistentSet<Types.NodeName>;
};
interface RowState {
update: number;
};
interface HeaderProps {
settings: AppState.Settings;
};
@@ -88,7 +92,7 @@ function formatCPU(cpu: number, stamp: Maybe<Types.Timestamp>): string {
return `${cpu.toFixed(fractionDigits)}%${ago}`;
}
export default class Row extends React.Component<RowProps, {}> {
export default class Row extends React.Component<RowProps, RowState> {
public static readonly columns: Column[] = [
{
label: 'Node',
@@ -236,6 +240,24 @@ export default class Row extends React.Component<RowProps, {}> {
)
}
public state = { update: 0 };
public componentDidMount() {
const { node } = this.props;
node.subscribe(this.onUpdate);
}
public componentWillUnmount() {
const { node } = this.props;
node.unsubscribe(this.onUpdate);
}
public shouldComponentUpdate(nextProps: RowProps, nextState: RowState): boolean {
return this.props.node.id !== nextProps.node.id || this.state.update !== nextState.update;
}
public render() {
const { node, settings } = this.props;
@@ -269,4 +291,8 @@ export default class Row extends React.Component<RowProps, {}> {
pins.add(node.name);
}
}
private onUpdate = () => {
this.setState({ update: this.state.update + 1 });
}
}
+31
View File
@@ -41,6 +41,8 @@ export class Node {
public lon: Maybe<Types.Longitude>;
public city: Maybe<Types.City>;
private readonly subscribtions = new Set<(node: Node) => void>();
constructor(
pinned: boolean,
id: Types.NodeId,
@@ -74,6 +76,8 @@ export class Node {
this.peers = peers;
this.txs = txs;
this.trigger();
}
public updateHardware(hardware: Types.NodeHardware) {
@@ -82,6 +86,8 @@ export class Node {
this.mem = mem;
this.cpu = cpu;
this.chartstamps = chartstamps;
this.trigger();
}
public updateBlock(block: Types.BlockDetails) {
@@ -92,6 +98,8 @@ export class Node {
this.blockTime = blockTime;
this.blockTimestamp = blockTimestamp;
this.propagationTime = propagationTime;
this.trigger();
}
public updateLocation(location: Types.NodeLocation) {
@@ -100,6 +108,29 @@ export class Node {
this.lat = lat;
this.lon = lon;
this.city = city;
this.trigger();
}
public newBestBlock() {
if (this.propagationTime != null) {
this.propagationTime = null;
this.trigger();
}
}
public subscribe(handler: (node: Node) => void) {
this.subscribtions.add(handler);
}
public unsubscribe(handler: (node: Node) => void) {
this.subscribtions.delete(handler);
}
private trigger() {
for (const handler of this.subscribtions.values()) {
handler(this);
}
}
}