diff --git a/presto-ui/src/router/ClusterHUD.jsx b/presto-ui/src/router/ClusterHUD.jsx
index 38bf01e9618bb..002b3ec0888ac 100755
--- a/presto-ui/src/router/ClusterHUD.jsx
+++ b/presto-ui/src/router/ClusterHUD.jsx
@@ -12,7 +12,7 @@
* limitations under the License.
*/
-import React from "react";
+import React, { useState, useEffect, useRef } from "react";
import {
addExponentiallyWeightedToHistory,
@@ -32,124 +32,136 @@ const SPARKLINE_PROPERTIES = {
disableHiddenCheck: true,
};
-export class ClusterHUD extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- runningQueries: [],
- queuedQueries: [],
- blockedQueries: [],
- activeWorkers: [],
- runningDrivers: [],
- reservedMemory: [],
- rowInputRate: [],
- byteInputRate: [],
- perWorkerCpuTimeRate: [],
- clusterCount: [],
+export const ClusterHUD = () => {
+ const [state, setState] = useState({
+ runningQueries: [],
+ queuedQueries: [],
+ blockedQueries: [],
+ activeWorkers: [],
+ runningDrivers: [],
+ reservedMemory: [],
+ rowInputRate: [],
+ byteInputRate: [],
+ perWorkerCpuTimeRate: [],
+ clusterCount: [],
- lastRender: null,
- lastRefresh: null,
+ lastRender: null,
+ lastRefresh: null,
- lastInputRows: null,
- lastInputBytes: null,
- lastCpuTime: null,
+ lastInputRows: null,
+ lastInputBytes: null,
+ lastCpuTime: null,
- initialized: false,
- };
+ initialized: false,
+ });
- this.refreshLoop = this.refreshLoop.bind(this);
- }
+ const timeoutId = useRef(null);
- resetTimer() {
- clearTimeout(this.timeoutId);
- // stop refreshing when query finishes or fails
- if (this.state.query === null || !this.state.ended) {
- this.timeoutId = setTimeout(this.refreshLoop, 1000);
- }
- }
+ const resetTimer = () => {
+ clearTimeout(timeoutId.current);
+ timeoutId.current = setTimeout(refreshLoop, 1000);
+ };
- refreshLoop() {
- clearTimeout(this.timeoutId); // to stop multiple series of refreshLoop from going on simultaneously
+ const refreshLoop = () => {
+ clearTimeout(timeoutId.current); // to stop multiple series of refreshLoop from going on simultaneously
$.get('/v1/cluster', function (clusterState) {
+ setState(prevState => {
+ let newRowInputRate = [];
+ let newByteInputRate = [];
+ let newPerWorkerCpuTimeRate = [];
+ if (prevState.lastRefresh !== null) {
+ const rowsInputSinceRefresh = clusterState.totalInputRows - prevState.lastInputRows;
+ const bytesInputSinceRefresh = clusterState.totalInputBytes - prevState.lastInputBytes;
+ const cpuTimeSinceRefresh = clusterState.totalCpuTimeSecs - prevState.lastCpuTime;
+ const secsSinceRefresh = (Date.now() - prevState.lastRefresh) / 1000.0;
- let newRowInputRate = [];
- let newByteInputRate = [];
- let newPerWorkerCpuTimeRate = [];
- if (this.state.lastRefresh !== null) {
- const rowsInputSinceRefresh = clusterState.totalInputRows - this.state.lastInputRows;
- const bytesInputSinceRefresh = clusterState.totalInputBytes - this.state.lastInputBytes;
- const cpuTimeSinceRefresh = clusterState.totalCpuTimeSecs - this.state.lastCpuTime;
- const secsSinceRefresh = (Date.now() - this.state.lastRefresh) / 1000.0;
-
- newRowInputRate = addExponentiallyWeightedToHistory(rowsInputSinceRefresh / secsSinceRefresh, this.state.rowInputRate);
- newByteInputRate = addExponentiallyWeightedToHistory(bytesInputSinceRefresh / secsSinceRefresh, this.state.byteInputRate);
- newPerWorkerCpuTimeRate = addExponentiallyWeightedToHistory((cpuTimeSinceRefresh / clusterState.activeWorkers) / secsSinceRefresh, this.state.perWorkerCpuTimeRate);
- }
+ newRowInputRate = addExponentiallyWeightedToHistory(rowsInputSinceRefresh / secsSinceRefresh, prevState.rowInputRate);
+ newByteInputRate = addExponentiallyWeightedToHistory(bytesInputSinceRefresh / secsSinceRefresh, prevState.byteInputRate);
+ newPerWorkerCpuTimeRate = addExponentiallyWeightedToHistory((cpuTimeSinceRefresh / clusterState.activeWorkers) / secsSinceRefresh, prevState.perWorkerCpuTimeRate);
+ }
- this.setState({
- // instantaneous stats
- runningQueries: addToHistory(clusterState.runningQueries, this.state.runningQueries),
- queuedQueries: addToHistory(clusterState.queuedQueries, this.state.queuedQueries),
- blockedQueries: addToHistory(clusterState.blockedQueries, this.state.blockedQueries),
- activeWorkers: addToHistory(clusterState.activeWorkers, this.state.activeWorkers),
- clusterCount: addToHistory(clusterState.clusterCount, this.state.clusterCount),
+ return {
+ ...prevState,
+ // instantaneous stats
+ runningQueries: addToHistory(clusterState.runningQueries, prevState.runningQueries),
+ queuedQueries: addToHistory(clusterState.queuedQueries, prevState.queuedQueries),
+ blockedQueries: addToHistory(clusterState.blockedQueries, prevState.blockedQueries),
+ activeWorkers: addToHistory(clusterState.activeWorkers, prevState.activeWorkers),
+ clusterCount: addToHistory(clusterState.clusterCount, prevState.clusterCount),
- // moving averages
- runningDrivers: addExponentiallyWeightedToHistory(clusterState.runningDrivers, this.state.runningDrivers),
- reservedMemory: addExponentiallyWeightedToHistory(clusterState.reservedMemory, this.state.reservedMemory),
+ // moving averages
+ runningDrivers: addExponentiallyWeightedToHistory(clusterState.runningDrivers, prevState.runningDrivers),
+ reservedMemory: addExponentiallyWeightedToHistory(clusterState.reservedMemory, prevState.reservedMemory),
- // moving averages for diffs
- rowInputRate: newRowInputRate,
- byteInputRate: newByteInputRate,
- perWorkerCpuTimeRate: newPerWorkerCpuTimeRate,
+ // moving averages for diffs
+ rowInputRate: newRowInputRate,
+ byteInputRate: newByteInputRate,
+ perWorkerCpuTimeRate: newPerWorkerCpuTimeRate,
- lastInputRows: clusterState.totalInputRows,
- lastInputBytes: clusterState.totalInputBytes,
- lastCpuTime: clusterState.totalCpuTimeSecs,
+ lastInputRows: clusterState.totalInputRows,
+ lastInputBytes: clusterState.totalInputBytes,
+ lastCpuTime: clusterState.totalCpuTimeSecs,
- initialized: true,
+ initialized: true,
- lastRefresh: Date.now()
+ lastRefresh: Date.now()
+ };
});
- this.resetTimer();
- }.bind(this))
+ resetTimer();
+ })
.fail(function () {
- this.resetTimer();
- }.bind(this));
- }
+ resetTimer();
+ });
+ };
- componentDidMount() {
- this.refreshLoop();
- }
+ useEffect(() => {
+ refreshLoop();
+
+ return () => {
+ clearTimeout(timeoutId.current);
+ };
+ }, []);
- componentDidUpdate() {
+ useEffect(() => {
// prevent multiple calls to componentDidUpdate (resulting from calls to setState or otherwise) within the refresh interval from re-rendering sparklines/charts
- if (this.state.lastRender === null || (Date.now() - this.state.lastRender) >= 1000) {
+ if (state.lastRender === null || (Date.now() - state.lastRender) >= 1000) {
const renderTimestamp = Date.now();
- $('#running-queries-sparkline').sparkline(this.state.runningQueries, $.extend({}, SPARKLINE_PROPERTIES, {chartRangeMin: 0}));
- $('#blocked-queries-sparkline').sparkline(this.state.blockedQueries, $.extend({}, SPARKLINE_PROPERTIES, {chartRangeMin: 0}));
- $('#queued-queries-sparkline').sparkline(this.state.queuedQueries, $.extend({}, SPARKLINE_PROPERTIES, {chartRangeMin: 0}));
+ $('#running-queries-sparkline').sparkline(state.runningQueries, $.extend({}, SPARKLINE_PROPERTIES, {chartRangeMin: 0}));
+ $('#blocked-queries-sparkline').sparkline(state.blockedQueries, $.extend({}, SPARKLINE_PROPERTIES, {chartRangeMin: 0}));
+ $('#queued-queries-sparkline').sparkline(state.queuedQueries, $.extend({}, SPARKLINE_PROPERTIES, {chartRangeMin: 0}));
- $('#active-workers-sparkline').sparkline(this.state.activeWorkers, $.extend({}, SPARKLINE_PROPERTIES, {chartRangeMin: 0}));
- $('#cluster-count-sparkline').sparkline(this.state.clusterCount, $.extend({}, SPARKLINE_PROPERTIES, {chartRangeMin: 0}));
+ $('#active-workers-sparkline').sparkline(state.activeWorkers, $.extend({}, SPARKLINE_PROPERTIES, {chartRangeMin: 0}));
+ $('#cluster-count-sparkline').sparkline(state.clusterCount, $.extend({}, SPARKLINE_PROPERTIES, {chartRangeMin: 0}));
- $('#running-drivers-sparkline').sparkline(this.state.runningDrivers, $.extend({}, SPARKLINE_PROPERTIES, {numberFormatter: precisionRound}));
- $('#reserved-memory-sparkline').sparkline(this.state.reservedMemory, $.extend({}, SPARKLINE_PROPERTIES, {numberFormatter: formatDataSizeBytes}));
+ $('#running-drivers-sparkline').sparkline(state.runningDrivers, $.extend({}, SPARKLINE_PROPERTIES, {numberFormatter: precisionRound}));
+ $('#reserved-memory-sparkline').sparkline(state.reservedMemory, $.extend({}, SPARKLINE_PROPERTIES, {numberFormatter: formatDataSizeBytes}));
- $('#row-input-rate-sparkline').sparkline(this.state.rowInputRate, $.extend({}, SPARKLINE_PROPERTIES, {numberFormatter: formatCount}));
- $('#byte-input-rate-sparkline').sparkline(this.state.byteInputRate, $.extend({}, SPARKLINE_PROPERTIES, {numberFormatter: formatDataSizeBytes}));
- $('#cpu-time-rate-sparkline').sparkline(this.state.perWorkerCpuTimeRate, $.extend({}, SPARKLINE_PROPERTIES, {numberFormatter: precisionRound}));
+ $('#row-input-rate-sparkline').sparkline(state.rowInputRate, $.extend({}, SPARKLINE_PROPERTIES, {numberFormatter: formatCount}));
+ $('#byte-input-rate-sparkline').sparkline(state.byteInputRate, $.extend({}, SPARKLINE_PROPERTIES, {numberFormatter: formatDataSizeBytes}));
+ $('#cpu-time-rate-sparkline').sparkline(state.perWorkerCpuTimeRate, $.extend({}, SPARKLINE_PROPERTIES, {numberFormatter: precisionRound}));
- this.setState({
+ setState(prevState => ({
+ ...prevState,
lastRender: renderTimestamp
- });
+ }));
}
$('[data-bs-toggle="tooltip"]')?.tooltip?.();
- }
+ }, [
+ state.runningQueries,
+ state.blockedQueries,
+ state.queuedQueries,
+ state.activeWorkers,
+ state.clusterCount,
+ state.runningDrivers,
+ state.reservedMemory,
+ state.rowInputRate,
+ state.byteInputRate,
+ state.perWorkerCpuTimeRate
+ ]);
- render() {
- return (
+ return (
+
@@ -171,7 +183,7 @@ export class ClusterHUD extends React.Component {
- {this.state.runningQueries[this.state.runningQueries.length - 1]}
+ {state.runningQueries[state.runningQueries.length - 1]}
Loading ...
@@ -179,7 +191,7 @@ export class ClusterHUD extends React.Component {
- {this.state.clusterCount[this.state.clusterCount.length - 1]}
+ {state.clusterCount[state.clusterCount.length - 1]}
Loading ...
@@ -205,7 +217,7 @@ export class ClusterHUD extends React.Component {
- {this.state.queuedQueries[this.state.queuedQueries.length - 1]}
+ {state.queuedQueries[state.queuedQueries.length - 1]}
Loading ...
@@ -213,7 +225,7 @@ export class ClusterHUD extends React.Component {
- {this.state.activeWorkers[this.state.activeWorkers.length - 1]}
+ {state.activeWorkers[state.activeWorkers.length - 1]}
Loading ...
@@ -240,7 +252,7 @@ export class ClusterHUD extends React.Component {
- {this.state.blockedQueries[this.state.blockedQueries.length - 1]}
+ {state.blockedQueries[state.blockedQueries.length - 1]}
Loading ...
@@ -248,13 +260,13 @@ export class ClusterHUD extends React.Component {
- {formatCount(this.state.runningDrivers[this.state.runningDrivers.length - 1])}
+ {formatCount(state.runningDrivers[state.runningDrivers.length - 1])}
Loading ...
-
);
- }
+
+ );
}
diff --git a/presto-ui/src/router/PageTitle.jsx b/presto-ui/src/router/PageTitle.jsx
index e35938a9b19a0..c32caf237cad4 100755
--- a/presto-ui/src/router/PageTitle.jsx
+++ b/presto-ui/src/router/PageTitle.jsx
@@ -12,79 +12,69 @@
* limitations under the License.
*/
//@flow
-import React from "react";
+import React, { useState, useEffect, useRef } from "react";
-type Props = {
- title: string
-}
+export const PageTitle = (): React.Node => {
+ const [state, setState] = useState({
+ noConnection: false,
+ lightShown: false,
+ info: null,
+ lastSuccess: Date.now(),
+ modalShown: false,
+ errorText: null,
+ });
-type State = {
- noConnection: boolean,
- lightShown: boolean,
- info: ?any,
- lastSuccess: number,
- modalShown: boolean,
- errorText: ?string,
-}
+ const timeoutId = useRef
(null);
-export class PageTitle extends React.Component {
- timeoutId: TimeoutID;
-
- constructor(props: Props) {
- super(props);
- this.state = {
- noConnection: false,
- lightShown: false,
- info: null,
- lastSuccess: Date.now(),
- modalShown: false,
- errorText: null,
- };
- }
-
- refreshLoop: () => void = () => {
- clearTimeout(this.timeoutId);
+ const refreshLoop = () => {
+ clearTimeout(timeoutId.current);
fetch("/v1/info")
.then(response => response.json())
.then(info => {
- this.setState({
+ setState(prevState => ({
+ ...prevState,
info: info,
noConnection: false,
lastSuccess: Date.now(),
modalShown: false,
- });
+ }));
//$FlowFixMe$ Bootstrap 3 plugin
$('#no-connection-modal').hide();
- this.resetTimer();
+ resetTimer();
})
.catch(error => {
- this.setState({
+ setState(prevState => ({
+ ...prevState,
noConnection: true,
- lightShown: !this.state.lightShown,
+ lightShown: !prevState.lightShown,
errorText: error
- });
- this.resetTimer();
+ }));
+ resetTimer();
- if (!this.state.modalShown && (error || (Date.now() - this.state.lastSuccess) > 30 * 1000)) {
+ if (!state.modalShown && (error || (Date.now() - state.lastSuccess) > 30 * 1000)) {
//$FlowFixMe$ Bootstrap 3 plugin
$('#no-connection-modal').hide();
- this.setState({modalShown: true});
+ setState(prevState => ({...prevState, modalShown: true}));
}
});
- }
+ };
- resetTimer() {
- clearTimeout(this.timeoutId);
- this.timeoutId = setTimeout(this.refreshLoop.bind(this), 1000);
- }
+ const resetTimer = () => {
+ clearTimeout(timeoutId.current);
+ timeoutId.current = setTimeout(refreshLoop, 1000);
+ };
- componentDidMount() {
- this.refreshLoop.bind(this)();
- }
+ useEffect(() => {
+ refreshLoop();
+
+ return () => {
+ clearTimeout(timeoutId.current);
+ };
+ }, []);
- renderStatusLight(): any {
- if (this.state.noConnection) {
- if (this.state.lightShown) {
+ const renderStatusLight = () => {
+ if (state.noConnection) {
+ if (state.lightShown) {
return ;
}
else {
@@ -92,67 +82,65 @@ export class PageTitle extends React.Component {
}
}
return ;
- }
+ };
- render(): any {
- const info = this.state.info;
- if (!info) {
- return null;
- }
+ const { info } = state;
+ if (!info) {
+ return null;
+ }
- return (
-
-