Commit bf3fcd03 authored by Andrew Fontaine's avatar Andrew Fontaine

Merge branch 'polling-metrics-widget' into 'master'

Add polling to metrics widget

See merge request gitlab-org/gitlab!34314
parents fac0d3f9 cf583d92
import Visibility from 'visibilityjs';
import Poll from '~/lib/utils/poll';
import httpStatusCodes from '~/lib/utils/http_status';
import axios from '~/lib/utils/axios_utils';
import * as types from './mutation_types';
let eTagPoll;
export const clearEtagPoll = () => {
eTagPoll = null;
};
export const stopPolling = () => {
if (eTagPoll) eTagPoll.stop();
};
export const restartPolling = () => {
if (eTagPoll) eTagPoll.restart();
};
export const setEndpoint = ({ commit }, endpoint) => commit(types.SET_ENDPOINT, endpoint);
export const requestMetrics = ({ commit }) => commit(types.REQUEST_METRICS);
/**
* We need to poll the report endpoint while they are being parsed in the Backend.
* This can take up to one minute.
*
* Poll.js will handle etag response.
* While http status code is 204, it means it's parsing, and we'll keep polling
* When http status code is 200, it means parsing is done, we can show the results & stop polling
* When http status code is 500, it means parsing went wrong and we stop polling
*/
export const fetchMetrics = ({ state, dispatch }) => {
dispatch('requestMetrics');
return axios
.get(state.endpoint)
.then(response => dispatch('receiveMetricsSuccess', response.data))
.catch(() => dispatch('receiveMetricsError'));
eTagPoll = new Poll({
resource: {
getMetrics(endpoint) {
return axios.get(endpoint);
},
},
data: state.endpoint,
method: 'getMetrics',
successCallback: ({ status, data }) => dispatch('receiveMetricsSuccess', { status, data }),
errorCallback: () => dispatch('receiveMetricsError'),
});
if (!Visibility.hidden()) {
eTagPoll.makeRequest();
} else {
axios
.get(state.endpoint)
.then(({ status, data }) => dispatch('receiveMetricsSuccess', { status, data }))
.catch(() => dispatch('receiveMetricsError'));
}
Visibility.change(() => {
if (!Visibility.hidden() && state.isLoading) {
dispatch('restartPolling');
} else {
dispatch('stopPolling');
}
});
};
export const receiveMetricsSuccess = ({ commit }, response) => {
commit(types.RECEIVE_METRICS_SUCCESS, response);
export const receiveMetricsSuccess = ({ commit, dispatch }, { status, data }) => {
if (status === httpStatusCodes.OK) {
commit(types.RECEIVE_METRICS_SUCCESS, data);
dispatch('stopPolling');
}
};
export const receiveMetricsError = ({ commit }) => commit(types.RECEIVE_METRICS_ERROR);
export const receiveMetricsError = ({ commit, dispatch }) => {
commit(types.RECEIVE_METRICS_ERROR);
dispatch('stopPolling');
};
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {};
---
title: Add polling to metrics widget
merge_request: 34314
author:
type: changed
......@@ -5,6 +5,8 @@ import {
fetchMetrics,
receiveMetricsSuccess,
receiveMetricsError,
stopPolling,
clearEtagPoll,
} from 'ee/vue_shared/metrics_reports/store/actions';
import * as types from 'ee/vue_shared/metrics_reports/store/mutation_types';
import state from 'ee/vue_shared/metrics_reports/store/state';
......@@ -58,17 +60,26 @@ describe('metrics reports actions', () => {
});
describe('fetchMetrics', () => {
it('should call metrics endpoint', () => {
const data = {
metrics: [
{
name: 'name',
value: 'value',
},
],
};
const endpoint = '/mock-endpoint.json';
const data = {
metrics: [
{
name: 'name',
value: 'value',
},
],
};
const endpoint = '/mock-endpoint.json';
beforeEach(() => {
mockedState.endpoint = endpoint;
});
afterEach(() => {
stopPolling();
clearEtagPoll();
});
it('should call metrics endpoint', () => {
mock.onGet(endpoint).replyOnce(200, data);
return testAction(
......@@ -81,7 +92,7 @@ describe('metrics reports actions', () => {
type: 'requestMetrics',
},
{
payload: data,
payload: { status: 200, data },
type: 'receiveMetricsSuccess',
},
],
......@@ -89,8 +100,6 @@ describe('metrics reports actions', () => {
});
it('handles errors', () => {
const endpoint = '/mock-endpoint.json';
mockedState.endpoint = endpoint;
mock.onGet(endpoint).replyOnce(500);
return testAction(
......@@ -111,11 +120,11 @@ describe('metrics reports actions', () => {
});
describe('receiveMetricsSuccess', () => {
it('should commit request mutation', () => {
it('should commit request mutation with 200', () => {
const response = { metrics: [] };
return testAction(
receiveMetricsSuccess,
response,
{ status: 200, data: response },
mockedState,
[
{
......@@ -123,6 +132,17 @@ describe('metrics reports actions', () => {
payload: response,
},
],
[{ type: 'stopPolling' }],
);
});
it('should not commit request mutation with 204', () => {
const response = { metrics: [] };
return testAction(
receiveMetricsSuccess,
{ status: 204, data: response },
mockedState,
[],
[],
);
});
......@@ -139,7 +159,7 @@ describe('metrics reports actions', () => {
type: types.RECEIVE_METRICS_ERROR,
},
],
[],
[{ type: 'stopPolling' }],
);
});
});
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment