feat: Throttle meta request for large chat size (#10518)
For large accounts with huge volumes of messages, it can be very wasteful to make the meta request so often. It also puts un-necessary load on the DB bombarding it with so many requests. This PR fixes it by throttling the requests to 5 seconds for all users with more than 1000 accessible chats. ### Why not cache this value in the backend? Well, it's a bit tricky, since a user can have different permissions over inboxes and can see different chats, maintaining a cache for each of them is not effective, besides the requests will reach the server anyway.
This commit is contained in:
@@ -5,6 +5,7 @@ const state = {
|
|||||||
mineCount: 0,
|
mineCount: 0,
|
||||||
unAssignedCount: 0,
|
unAssignedCount: 0,
|
||||||
allCount: 0,
|
allCount: 0,
|
||||||
|
updatedOn: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getters = {
|
export const getters = {
|
||||||
@@ -12,7 +13,17 @@ export const getters = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
get: async ({ commit }, params) => {
|
get: async ({ commit, state: $state }, params) => {
|
||||||
|
const currentTime = new Date();
|
||||||
|
const lastUpdatedTime = new Date($state.updatedOn);
|
||||||
|
|
||||||
|
// Skip large accounts from making too many requests
|
||||||
|
if (currentTime - lastUpdatedTime < 10000 && $state.allCount > 1000) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.warn('Skipping conversation meta fetch');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await ConversationApi.meta(params);
|
const response = await ConversationApi.meta(params);
|
||||||
const {
|
const {
|
||||||
@@ -40,6 +51,7 @@ export const mutations = {
|
|||||||
$state.mineCount = mineCount;
|
$state.mineCount = mineCount;
|
||||||
$state.allCount = allCount;
|
$state.allCount = allCount;
|
||||||
$state.unAssignedCount = unAssignedCount;
|
$state.unAssignedCount = unAssignedCount;
|
||||||
|
$state.updatedOn = new Date();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ describe('#actions', () => {
|
|||||||
it('sends correct mutations if API is success', async () => {
|
it('sends correct mutations if API is success', async () => {
|
||||||
axios.get.mockResolvedValue({ data: { meta: { mine_count: 1 } } });
|
axios.get.mockResolvedValue({ data: { meta: { mine_count: 1 } } });
|
||||||
await actions.get(
|
await actions.get(
|
||||||
{ commit },
|
{ commit, state: { updatedOn: null } },
|
||||||
{ inboxId: 1, assigneeTpe: 'me', status: 'open' }
|
{ inboxId: 1, assigneeTpe: 'me', status: 'open' }
|
||||||
);
|
);
|
||||||
expect(commit.mock.calls).toEqual([
|
expect(commit.mock.calls).toEqual([
|
||||||
@@ -21,7 +21,7 @@ describe('#actions', () => {
|
|||||||
it('sends correct actions if API is error', async () => {
|
it('sends correct actions if API is error', async () => {
|
||||||
axios.get.mockRejectedValue({ message: 'Incorrect header' });
|
axios.get.mockRejectedValue({ message: 'Incorrect header' });
|
||||||
await actions.get(
|
await actions.get(
|
||||||
{ commit },
|
{ commit, state: { updatedOn: null } },
|
||||||
{ inboxId: 1, assigneeTpe: 'me', status: 'open' }
|
{ inboxId: 1, assigneeTpe: 'me', status: 'open' }
|
||||||
);
|
);
|
||||||
expect(commit.mock.calls).toEqual([]);
|
expect(commit.mock.calls).toEqual([]);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ describe('#mutations', () => {
|
|||||||
mineCount: 1,
|
mineCount: 1,
|
||||||
unAssignedCount: 1,
|
unAssignedCount: 1,
|
||||||
allCount: 2,
|
allCount: 2,
|
||||||
|
updatedOn: expect.any(Date),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user