BackendSrv: Cancellable requests & Observable all the way (#25746)

* BackendSrv: Observable all the way POC

* starting to unify code paths

* tests pass

* Unified error handling

* Single request path and error handling

* Fixed ts issue

* another ts issu

* Added back old requestId cancellation

* Slow progress trying to grasp the full picture of cancellation

* Updates

* refactoring

* Remove a bunch of stuff from backendSrv

* Removed another function

* Do not show error alerts for data queries

* Muu

* Updated comment

* fixed ts issue

* unify request options type

* Made query inspector subscribe to backendSrv stream instead of legacy app events

* Add back support for err.isHandled to limit scope

* never show success alerts

* Updated tests

* Fixing tests

* Minor weak

* Improved logic for the showErrorAlert and showSuccessAlert boolean flags, now they work more logically

* Fix issue
This commit is contained in:
Torkel Ödegaard
2020-07-07 21:22:47 +02:00
committed by GitHub
parent ba4a8256a4
commit 81e955e6b5
22 changed files with 722 additions and 801 deletions

View File

@@ -5,12 +5,13 @@ import { AppEvents, PanelEvents, DataFrame } from '@grafana/data';
import appEvents from 'app/core/app_events';
import { CopyToClipboard } from 'app/core/components/CopyToClipboard/CopyToClipboard';
import { CoreEvents } from 'app/types';
import { PanelModel } from 'app/features/dashboard/state';
import { getPanelInspectorStyles } from './styles';
import { supportsDataQuery } from '../PanelEditor/utils';
import { config } from '@grafana/runtime';
import { css } from 'emotion';
import { Unsubscribable } from 'rxjs';
import { backendSrv } from 'app/core/services/backend_srv';
interface DsQuery {
isLoading: boolean;
@@ -40,6 +41,7 @@ interface State {
export class QueryInspector extends PureComponent<Props, State> {
formattedJson: any;
clipboard: any;
subscription?: Unsubscribable;
constructor(props: Props) {
super(props);
@@ -56,8 +58,10 @@ export class QueryInspector extends PureComponent<Props, State> {
}
componentDidMount() {
appEvents.on(CoreEvents.dsRequestResponse, this.onDataSourceResponse);
appEvents.on(CoreEvents.dsRequestError, this.onRequestError);
this.subscription = backendSrv.getInspectorStream().subscribe({
next: response => this.onDataSourceResponse(response),
});
this.props.panel.events.on(PanelEvents.refresh, this.onPanelRefresh);
this.updateQueryList();
}
@@ -74,12 +78,16 @@ export class QueryInspector extends PureComponent<Props, State> {
updateQueryList() {
const { data } = this.props;
const executedQueries: ExecutedQueryInfo[] = [];
if (data?.length) {
let last: ExecutedQueryInfo | undefined = undefined;
data.forEach((frame, idx) => {
const query = frame.meta?.executedQueryString;
if (query) {
const refId = frame.refId || '?';
if (last?.refId === refId) {
last.frames++;
last.rows += frame.length;
@@ -95,6 +103,7 @@ export class QueryInspector extends PureComponent<Props, State> {
}
});
}
this.setState({ executedQueries });
}
@@ -105,23 +114,11 @@ export class QueryInspector extends PureComponent<Props, State> {
componentWillUnmount() {
const { panel } = this.props;
appEvents.off(CoreEvents.dsRequestResponse, this.onDataSourceResponse);
appEvents.on(CoreEvents.dsRequestError, this.onRequestError);
panel.events.off(PanelEvents.refresh, this.onPanelRefresh);
}
handleMocking(response: any) {
const { mockedResponse } = this.state;
let mockedData;
try {
mockedData = JSON.parse(mockedResponse);
} catch (err) {
appEvents.emit(AppEvents.alertError, ['R: Failed to parse mocked response']);
return;
if (this.subscription) {
this.subscription.unsubscribe();
}
response.data = mockedData;
panel.events.off(PanelEvents.refresh, this.onPanelRefresh);
}
onPanelRefresh = () => {
@@ -134,13 +131,9 @@ export class QueryInspector extends PureComponent<Props, State> {
}));
};
onRequestError = (err: any) => {
this.onDataSourceResponse(err);
};
onDataSourceResponse = (response: any = {}) => {
if (this.state.isMocking) {
this.handleMocking(response);
onDataSourceResponse(response: any) {
// ignore silent requests
if (response.config?.silent) {
return;
}
@@ -186,7 +179,7 @@ export class QueryInspector extends PureComponent<Props, State> {
response: response,
},
}));
};
}
setFormattedJson = (formattedJson: any) => {
this.formattedJson = formattedJson;