Commit cdcfabba authored by Thomas Randolph's avatar Thomas Randolph Committed by Phil Hughes

Limit discussions.json requests to maximum 2 in one batch

parent f8715e0f
...@@ -22,6 +22,8 @@ export const TIME_DIFFERENCE_VALUE = 10; ...@@ -22,6 +22,8 @@ export const TIME_DIFFERENCE_VALUE = 10;
export const ASC = 'asc'; export const ASC = 'asc';
export const DESC = 'desc'; export const DESC = 'desc';
export const DISCUSSION_FETCH_TIMEOUT = 750;
export const NOTEABLE_TYPE_MAPPING = { export const NOTEABLE_TYPE_MAPPING = {
Issue: ISSUE_NOTEABLE_TYPE, Issue: ISSUE_NOTEABLE_TYPE,
MergeRequest: MERGE_REQUEST_NOTEABLE_TYPE, MergeRequest: MERGE_REQUEST_NOTEABLE_TYPE,
......
...@@ -87,6 +87,7 @@ export const fetchDiscussions = ({ commit, dispatch }, { path, filter, persistFi ...@@ -87,6 +87,7 @@ export const fetchDiscussions = ({ commit, dispatch }, { path, filter, persistFi
return axios.get(path, config).then(({ data }) => { return axios.get(path, config).then(({ data }) => {
commit(types.SET_INITIAL_DISCUSSIONS, data); commit(types.SET_INITIAL_DISCUSSIONS, data);
commit(types.SET_FETCHING_DISCUSSIONS, false);
dispatch('updateResolvableDiscussionsCounts'); dispatch('updateResolvableDiscussionsCounts');
}); });
...@@ -136,6 +137,23 @@ export const updateNote = ({ commit, dispatch }, { endpoint, note }) => ...@@ -136,6 +137,23 @@ export const updateNote = ({ commit, dispatch }, { endpoint, note }) =>
export const updateOrCreateNotes = ({ commit, state, getters, dispatch }, notes) => { export const updateOrCreateNotes = ({ commit, state, getters, dispatch }, notes) => {
const { notesById } = getters; const { notesById } = getters;
const debouncedFetchDiscussions = isFetching => {
if (!isFetching) {
commit(types.SET_FETCHING_DISCUSSIONS, true);
dispatch('fetchDiscussions', { path: state.notesData.discussionsPath });
} else {
if (isFetching !== true) {
clearTimeout(state.currentlyFetchingDiscussions);
}
commit(
types.SET_FETCHING_DISCUSSIONS,
setTimeout(() => {
dispatch('fetchDiscussions', { path: state.notesData.discussionsPath });
}, constants.DISCUSSION_FETCH_TIMEOUT),
);
}
};
notes.forEach(note => { notes.forEach(note => {
if (notesById[note.id]) { if (notesById[note.id]) {
...@@ -146,7 +164,7 @@ export const updateOrCreateNotes = ({ commit, state, getters, dispatch }, notes) ...@@ -146,7 +164,7 @@ export const updateOrCreateNotes = ({ commit, state, getters, dispatch }, notes)
if (discussion) { if (discussion) {
commit(types.ADD_NEW_REPLY_TO_DISCUSSION, note); commit(types.ADD_NEW_REPLY_TO_DISCUSSION, note);
} else if (note.type === constants.DIFF_NOTE) { } else if (note.type === constants.DIFF_NOTE) {
dispatch('fetchDiscussions', { path: state.notesData.discussionsPath }); debouncedFetchDiscussions(state.currentlyFetchingDiscussions);
} else { } else {
commit(types.ADD_NEW_NOTE, note); commit(types.ADD_NEW_NOTE, note);
} }
......
...@@ -12,6 +12,7 @@ export default () => ({ ...@@ -12,6 +12,7 @@ export default () => ({
lastFetchedAt: null, lastFetchedAt: null,
currentDiscussionId: null, currentDiscussionId: null,
batchSuggestionsInfo: [], batchSuggestionsInfo: [],
currentlyFetchingDiscussions: false,
/** /**
* selectedCommentPosition & selectedCommentPosition structures are the same as `position.line_range`: * selectedCommentPosition & selectedCommentPosition structures are the same as `position.line_range`:
* { * {
......
...@@ -36,6 +36,7 @@ export const SET_CURRENT_DISCUSSION_ID = 'SET_CURRENT_DISCUSSION_ID'; ...@@ -36,6 +36,7 @@ export const SET_CURRENT_DISCUSSION_ID = 'SET_CURRENT_DISCUSSION_ID';
export const SET_DISCUSSIONS_SORT = 'SET_DISCUSSIONS_SORT'; export const SET_DISCUSSIONS_SORT = 'SET_DISCUSSIONS_SORT';
export const SET_SELECTED_COMMENT_POSITION = 'SET_SELECTED_COMMENT_POSITION'; export const SET_SELECTED_COMMENT_POSITION = 'SET_SELECTED_COMMENT_POSITION';
export const SET_SELECTED_COMMENT_POSITION_HOVER = 'SET_SELECTED_COMMENT_POSITION_HOVER'; export const SET_SELECTED_COMMENT_POSITION_HOVER = 'SET_SELECTED_COMMENT_POSITION_HOVER';
export const SET_FETCHING_DISCUSSIONS = 'SET_FETCHING_DISCUSSIONS';
// Issue // Issue
export const CLOSE_ISSUE = 'CLOSE_ISSUE'; export const CLOSE_ISSUE = 'CLOSE_ISSUE';
......
...@@ -379,4 +379,7 @@ export default { ...@@ -379,4 +379,7 @@ export default {
[types.UPDATE_ASSIGNEES](state, assignees) { [types.UPDATE_ASSIGNEES](state, assignees) {
state.noteableData.assignees = assignees; state.noteableData.assignees = assignees;
}, },
[types.SET_FETCHING_DISCUSSIONS](state, value) {
state.currentlyFetchingDiscussions = value;
},
}; };
...@@ -3,6 +3,7 @@ import AxiosMockAdapter from 'axios-mock-adapter'; ...@@ -3,6 +3,7 @@ import AxiosMockAdapter from 'axios-mock-adapter';
import Api from '~/api'; import Api from '~/api';
import { deprecatedCreateFlash as Flash } from '~/flash'; import { deprecatedCreateFlash as Flash } from '~/flash';
import * as actions from '~/notes/stores/actions'; import * as actions from '~/notes/stores/actions';
import mutations from '~/notes/stores/mutations';
import * as mutationTypes from '~/notes/stores/mutation_types'; import * as mutationTypes from '~/notes/stores/mutation_types';
import * as notesConstants from '~/notes/constants'; import * as notesConstants from '~/notes/constants';
import createStore from '~/notes/stores'; import createStore from '~/notes/stores';
...@@ -651,6 +652,26 @@ describe('Actions Notes Store', () => { ...@@ -651,6 +652,26 @@ describe('Actions Notes Store', () => {
}); });
describe('updateOrCreateNotes', () => { describe('updateOrCreateNotes', () => {
it('Prevents `fetchDiscussions` being called multiple times within time limit', () => {
jest.useFakeTimers();
const note = { id: 1234, type: notesConstants.DIFF_NOTE };
const getters = { notesById: {} };
state = { discussions: [note], notesData: { discussionsPath: '' } };
commit.mockImplementation((type, value) => {
if (type === mutationTypes.SET_FETCHING_DISCUSSIONS) {
mutations[type](state, value);
}
});
actions.updateOrCreateNotes({ commit, state, getters, dispatch }, [note]);
actions.updateOrCreateNotes({ commit, state, getters, dispatch }, [note]);
jest.runAllTimers();
actions.updateOrCreateNotes({ commit, state, getters, dispatch }, [note]);
expect(dispatch).toHaveBeenCalledTimes(2);
});
it('Updates existing note', () => { it('Updates existing note', () => {
const note = { id: 1234 }; const note = { id: 1234 };
const getters = { notesById: { 1234: note } }; const getters = { notesById: { 1234: note } };
......
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