125 lines
3.4 KiB
JavaScript
125 lines
3.4 KiB
JavaScript
/**
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
* KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations
|
|
* under the License.
|
|
*/
|
|
import React from 'react';
|
|
import PropTypes from 'prop-types';
|
|
import { bindActionCreators } from 'redux';
|
|
import { connect } from 'react-redux';
|
|
import { SupersetClient } from '@superset-ui/core';
|
|
import * as Actions from 'src/SqlLab/actions/sqlLab';
|
|
|
|
const QUERY_UPDATE_FREQ = 2000;
|
|
const QUERY_UPDATE_BUFFER_MS = 5000;
|
|
const MAX_QUERY_AGE_TO_POLL = 21600000;
|
|
const QUERY_TIMEOUT_LIMIT = 10000;
|
|
|
|
class QueryAutoRefresh extends React.PureComponent {
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = {
|
|
offline: props.offline,
|
|
};
|
|
}
|
|
|
|
UNSAFE_componentWillMount() {
|
|
this.startTimer();
|
|
}
|
|
|
|
componentDidUpdate(prevProps) {
|
|
if (prevProps.offline !== this.state.offline) {
|
|
this.props.actions.setUserOffline(this.state.offline);
|
|
}
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
this.stopTimer();
|
|
}
|
|
|
|
shouldCheckForQueries() {
|
|
// if there are started or running queries, this method should return true
|
|
const { queries } = this.props;
|
|
const now = new Date().getTime();
|
|
const isQueryRunning = q =>
|
|
['running', 'started', 'pending', 'fetching'].indexOf(q.state) >= 0;
|
|
|
|
return Object.values(queries).some(
|
|
q => isQueryRunning(q) && now - q.startDttm < MAX_QUERY_AGE_TO_POLL,
|
|
);
|
|
}
|
|
|
|
startTimer() {
|
|
if (!this.timer) {
|
|
this.timer = setInterval(this.stopwatch.bind(this), QUERY_UPDATE_FREQ);
|
|
}
|
|
}
|
|
|
|
stopTimer() {
|
|
clearInterval(this.timer);
|
|
this.timer = null;
|
|
}
|
|
|
|
stopwatch() {
|
|
// only poll /superset/queries/ if there are started or running queries
|
|
if (this.shouldCheckForQueries()) {
|
|
SupersetClient.get({
|
|
endpoint: `/superset/queries/${
|
|
this.props.queriesLastUpdate - QUERY_UPDATE_BUFFER_MS
|
|
}`,
|
|
timeout: QUERY_TIMEOUT_LIMIT,
|
|
})
|
|
.then(({ json }) => {
|
|
if (Object.keys(json).length > 0) {
|
|
this.props.actions.refreshQueries(json);
|
|
}
|
|
this.setState({ offline: false });
|
|
})
|
|
.catch(() => {
|
|
this.setState({ offline: true });
|
|
});
|
|
} else {
|
|
this.setState({ offline: false });
|
|
}
|
|
}
|
|
|
|
render() {
|
|
return null;
|
|
}
|
|
}
|
|
QueryAutoRefresh.propTypes = {
|
|
offline: PropTypes.bool.isRequired,
|
|
queries: PropTypes.object.isRequired,
|
|
actions: PropTypes.object.isRequired,
|
|
queriesLastUpdate: PropTypes.number.isRequired,
|
|
};
|
|
|
|
function mapStateToProps({ sqlLab }) {
|
|
return {
|
|
offline: sqlLab.offline,
|
|
queries: sqlLab.queries,
|
|
queriesLastUpdate: sqlLab.queriesLastUpdate,
|
|
};
|
|
}
|
|
|
|
function mapDispatchToProps(dispatch) {
|
|
return {
|
|
actions: bindActionCreators(Actions, dispatch),
|
|
};
|
|
}
|
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(QueryAutoRefresh);
|