From e3584add7c723530783156f99700edbb581cdf43 Mon Sep 17 00:00:00 2001 From: Thomas Nordquist Date: Mon, 8 Jul 2019 00:19:34 +0200 Subject: [PATCH] Fix broker stats --- .../ChartPanel/ChartWithTreeNode.tsx | 36 +----- .../SettingsDrawer/BrokerStatistics.tsx | 105 +++++++++--------- .../helper/usePollingToFetchTreeNode.tsx | 38 +++++++ 3 files changed, 94 insertions(+), 85 deletions(-) create mode 100644 app/src/components/helper/usePollingToFetchTreeNode.tsx diff --git a/app/src/components/ChartPanel/ChartWithTreeNode.tsx b/app/src/components/ChartPanel/ChartWithTreeNode.tsx index 2fd812c..4f910c4 100644 --- a/app/src/components/ChartPanel/ChartWithTreeNode.tsx +++ b/app/src/components/ChartPanel/ChartWithTreeNode.tsx @@ -1,7 +1,8 @@ import * as q from '../../../../backend/src/Model' -import * as React from 'react' +import React from 'react' import Chart from './Chart' import { ChartParameters } from '../../reducers/Charts' +import { usePollingToFetchTreeNode } from '../helper/usePollingToFetchTreeNode' interface Props { tree?: q.Tree @@ -14,37 +15,6 @@ export function ChartWithTreeNode(props: Props) { return null } - const initialTreeNode = tree.findNode(parameters.topic) - const [treeNode, setTreeNode] = React.useState | undefined>(initialTreeNode) - - usePollingToFetchTreeNode(treeNode, tree, parameters.topic, setTreeNode) + const treeNode = usePollingToFetchTreeNode(tree, parameters.topic) return } - -/** - * If a node is not available when the plot is shown, keep polling until it has been created - */ -function usePollingToFetchTreeNode( - treeNode: q.TreeNode | undefined, - tree: q.Tree, - path: string, - setTreeNode: React.Dispatch | undefined>> -) { - function pollUntilTreeNodeHasBeenFound() { - let intervalTimer: any - if (!treeNode) { - intervalTimer = setInterval(() => { - const node = tree.findNode(path) - if (node) { - setTreeNode(node) - clearInterval(intervalTimer) - } - }, 500) - } - return function cleanup() { - intervalTimer && clearInterval(intervalTimer) - } - } - - React.useEffect(pollUntilTreeNodeHasBeenFound, []) -} diff --git a/app/src/components/SettingsDrawer/BrokerStatistics.tsx b/app/src/components/SettingsDrawer/BrokerStatistics.tsx index 9f5e716..637a60f 100644 --- a/app/src/components/SettingsDrawer/BrokerStatistics.tsx +++ b/app/src/components/SettingsDrawer/BrokerStatistics.tsx @@ -1,13 +1,12 @@ import * as q from '../../../../backend/src/Model' -import * as React from 'react' +import React, { useMemo } from 'react' import { AppState } from '../../reducers' +import { Base64Message } from '../../../../backend/src/Model/Base64Message' import { connect } from 'react-redux' -import { StyleRulesCallback, withStyles, Theme } from '@material-ui/core/styles' +import { Theme, withStyles } from '@material-ui/core/styles' import { TopicViewModel } from '../../model/TopicViewModel' import { Typography } from '@material-ui/core' -import { Base64Message } from '../../../../backend/src/Model/Base64Message' -import teal from '@material-ui/core/colors/teal' - +import { usePollingToFetchTreeNode } from '../helper/usePollingToFetchTreeNode' const abbreviate = require('number-abbreviate') interface Stats { @@ -16,10 +15,6 @@ interface Stats { } const styles = (theme: Theme) => ({ - flex: { - display: 'flex', - width: '100%', - }, container: { width: '100%', height: '224px', @@ -34,24 +29,12 @@ interface Props { tree?: q.Tree } -class BrokerStatistics extends React.Component { - constructor(props: any) { - super(props) - this.state = {} - } +function BrokerStatistics(props: Props) { + const { tree, classes } = props + const sysTopic = usePollingToFetchTreeNode(props.tree, '$SYS') - private renderPair(tree: q.Tree, a: Stats, b: Stats) { - return ( -
-
{this.renderStat(tree, a)}
-
{this.renderStat(tree, b)}
-
- ) - } - - public render() { - const { tree, classes } = this.props - if (!tree || !tree.findNode('$SYS/broker/clients/total')) { + return useMemo(() => { + if (!Boolean(sysTopic)) { return null } @@ -94,38 +77,20 @@ class BrokerStatistics extends React.Component { }, } - return ( -
- {this.renderStat(tree, stats.broker)} - {this.renderPair(tree, stats.sent, stats.received)} - {this.renderPair(tree, stats.clients, stats.subscriptions)} - {this.renderPair(tree, stats.sent5m, stats.received5m)} - {this.renderPair(tree, stats.heap, stats.heapMax)} -
- ) - } - - public renderStat(tree: q.Tree, stat: Stats) { - const node = tree.findNode(stat.topic) - if (!node || !node.message) { + if (!tree) { return null } - const str = node.message.value ? Base64Message.toUnicodeString(node.message.value) : '' - let value = node.message && node.message.value ? parseFloat(str) : NaN - value = !isNaN(value) ? abbreviate(value) : str - return ( -
- - {stat.title} - - - {value} - +
+ {renderStat(tree, stats.broker)} + {renderPair(tree, stats.sent, stats.received)} + {renderPair(tree, stats.clients, stats.subscriptions)} + {renderPair(tree, stats.sent5m, stats.received5m)} + {renderPair(tree, stats.heap, stats.heapMax)}
) - } + }, [sysTopic && sysTopic.lastUpdate]) } const mapStateToProps = (state: AppState) => { @@ -135,3 +100,39 @@ const mapStateToProps = (state: AppState) => { } export default withStyles(styles)(connect(mapStateToProps)(BrokerStatistics)) + +function renderPair(tree: q.Tree, a: Stats, b: Stats) { + return ( +
+
{renderStat(tree, a)}
+
{renderStat(tree, b)}
+
+ ) +} + +function renderStat(tree: q.Tree, stat: Stats) { + const node = tree.findNode(stat.topic) + if (!node || !node.message) { + return null + } + + const str = node.message.value ? Base64Message.toUnicodeString(node.message.value) : '' + let value = node.message && node.message.value ? parseFloat(str) : NaN + value = !isNaN(value) ? abbreviate(value) : str + + return ( +
+ + {stat.title} + + + {value} + +
+ ) +} diff --git a/app/src/components/helper/usePollingToFetchTreeNode.tsx b/app/src/components/helper/usePollingToFetchTreeNode.tsx new file mode 100644 index 0000000..3cd8697 --- /dev/null +++ b/app/src/components/helper/usePollingToFetchTreeNode.tsx @@ -0,0 +1,38 @@ +import * as q from '../../../../backend/src/Model' +import { useState, useEffect } from 'react' + +/** + * If a node is not available when the plot is shown, keep polling until it has been created + */ +export function usePollingToFetchTreeNode(tree: q.Tree | undefined, path: string) { + const [treeNode, setTreeNode] = useState | undefined>() + + function pollUntilTreeNodeHasBeenFound() { + if (!tree) { + return + } + + const initialTreeNode = tree.findNode(path) + if (initialTreeNode) { + setTreeNode(initialTreeNode) + return + } + + let intervalTimer: any + if (!treeNode) { + intervalTimer = setInterval(() => { + const node = tree.findNode(path) + if (node) { + setTreeNode(node) + clearInterval(intervalTimer) + } + }, 500) + } + return function cleanup() { + intervalTimer && clearInterval(intervalTimer) + } + } + + useEffect(pollUntilTreeNodeHasBeenFound, [tree]) + return treeNode +}