Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically update metric plots for in-progress runs #2099 #5017

Merged
merged 21 commits into from Dec 2, 2021
Expand Up @@ -2,11 +2,11 @@ import React from 'react';
import { connect } from 'react-redux';
import Utils from '../../common/utils/Utils';
import RequestStateWrapper from '../../common/components/RequestStateWrapper';
import { getMetricHistoryApi } from '../actions';
import { getMetricHistoryApi, getRunApi } from '../actions';
import PropTypes from 'prop-types';
import _ from 'lodash';
import { MetricsPlotView } from './MetricsPlotView';
import { getRunTags } from '../reducers/Reducers';
import { getRunTags, getRunInfo } from '../reducers/Reducers';
import {
MetricsPlotControls,
X_AXIS_WALL,
Expand Down Expand Up @@ -37,6 +37,8 @@ export class MetricsPlotPanel extends React.Component {
location: PropTypes.object.isRequired,
history: PropTypes.object.isRequired,
runDisplayNames: PropTypes.arrayOf(PropTypes.string).isRequired,
runs: PropTypes.arrayOf(PropTypes.object),
getRunApi: PropTypes.func,
};

// The fields below are exposed as instance attributes rather than component state so that they
Expand All @@ -63,6 +65,8 @@ export class MetricsPlotPanel extends React.Component {
// a single-click event.
SINGLE_CLICK_EVENT_DELAY_MS = this.MAX_DOUBLE_CLICK_INTERVAL_MS + 10;

DURATION_BETWEEN_HISTORY_UPDATES_MS = 8000;
cedkoffeto marked this conversation as resolved.
Show resolved Hide resolved

constructor(props) {
super(props);
this.state = {
Expand All @@ -71,11 +75,47 @@ export class MetricsPlotPanel extends React.Component {
popoverX: 0,
popoverY: 0,
popoverRunItems: [],
timerId: null,
};
this.displayPopover = false;
this.loadMetricHistory(this.props.runUuids, this.getUrlState().selectedMetricKeys);
}

componentDidMount() {
const { runs } = this.props;

if (runs && this.checkOnRunUnfinished()) {
const timerId = setInterval(() => {
let requestIds = [];

if (this.checkOnRunUnfinished()) {
const getRequestIds = this.loadMetricHistory(
this.props.runUuids,
this.getUrlState().selectedMetricKeys,
);
requestIds = [...requestIds, ...getRequestIds];

this.props.runs.forEach((run) => {
const runUuid = run.getRunUuid();

const getRunRequestId = getUUID();
requestIds.push(getRunRequestId);
this.props.getRunApi(runUuid, getRunRequestId);
});

this.setState((prevState) => ({
historyRequestIds: [...prevState.historyRequestIds, ...requestIds],
}));
} else {
clearInterval(this.state.timerId);
}
}, this.DURATION_BETWEEN_HISTORY_UPDATES_MS);

// eslint-disable-next-line react/no-did-mount-set-state
this.setState({ timerId });
}
}

getUrlState() {
return Utils.getMetricPlotStateFromUrl(this.props.location.search);
}
Expand Down Expand Up @@ -459,6 +499,18 @@ export class MetricsPlotPanel extends React.Component {
}, 300);
};

checkOnRunUnfinished() {
const { runs } = this.props;

let boolean = false;
runs &&
runs.forEach((run) => {
if (run.getStatus() === 'RUNNING') boolean = true;
});

return boolean;
}

harupy marked this conversation as resolved.
Show resolved Hide resolved
render() {
const { experimentId, runUuids, runDisplayNames, distinctMetricKeys, location } = this.props;
const { popoverVisible, popoverX, popoverY, popoverRunItems } = this.state;
Expand Down Expand Up @@ -536,6 +588,7 @@ const mapStateToProps = (state, ownProps) => {
const distinctMetricKeys = [...new Set(metricKeys)].sort();

const runDisplayNames = [];
const runs = runUuids.map((runUuid) => getRunInfo(runUuid, state));

// Flat array of all metrics, with history and information of the run it belongs to
// This is used for underlying MetricsPlotView & predicting chartType for MetricsPlotControls
Expand All @@ -561,9 +614,11 @@ const mapStateToProps = (state, ownProps) => {
latestMetricsByRunUuid,
distinctMetricKeys,
metricsWithRunInfoAndHistory,
runs,
state,
};
};

const mapDispatchToProps = { getMetricHistoryApi };
const mapDispatchToProps = { getMetricHistoryApi, getRunApi };

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(MetricsPlotPanel));