From 3fd585f40b477efad373a518eb87918c6c591f30 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 6 Dec 2024 12:05:30 +0530 Subject: [PATCH] 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. --- .../dashboard/store/modules/conversationStats.js | 14 +++++++++++++- .../specs/conversationStats/actions.spec.js | 4 ++-- .../specs/conversationStats/mutations.spec.js | 1 + 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/app/javascript/dashboard/store/modules/conversationStats.js b/app/javascript/dashboard/store/modules/conversationStats.js index 201bf6564..025e3352f 100644 --- a/app/javascript/dashboard/store/modules/conversationStats.js +++ b/app/javascript/dashboard/store/modules/conversationStats.js @@ -5,6 +5,7 @@ const state = { mineCount: 0, unAssignedCount: 0, allCount: 0, + updatedOn: null, }; export const getters = { @@ -12,7 +13,17 @@ export const getters = { }; 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 { const response = await ConversationApi.meta(params); const { @@ -40,6 +51,7 @@ export const mutations = { $state.mineCount = mineCount; $state.allCount = allCount; $state.unAssignedCount = unAssignedCount; + $state.updatedOn = new Date(); }, }; diff --git a/app/javascript/dashboard/store/modules/specs/conversationStats/actions.spec.js b/app/javascript/dashboard/store/modules/specs/conversationStats/actions.spec.js index 33d927103..4572387ac 100644 --- a/app/javascript/dashboard/store/modules/specs/conversationStats/actions.spec.js +++ b/app/javascript/dashboard/store/modules/specs/conversationStats/actions.spec.js @@ -11,7 +11,7 @@ describe('#actions', () => { it('sends correct mutations if API is success', async () => { axios.get.mockResolvedValue({ data: { meta: { mine_count: 1 } } }); await actions.get( - { commit }, + { commit, state: { updatedOn: null } }, { inboxId: 1, assigneeTpe: 'me', status: 'open' } ); expect(commit.mock.calls).toEqual([ @@ -21,7 +21,7 @@ describe('#actions', () => { it('sends correct actions if API is error', async () => { axios.get.mockRejectedValue({ message: 'Incorrect header' }); await actions.get( - { commit }, + { commit, state: { updatedOn: null } }, { inboxId: 1, assigneeTpe: 'me', status: 'open' } ); expect(commit.mock.calls).toEqual([]); diff --git a/app/javascript/dashboard/store/modules/specs/conversationStats/mutations.spec.js b/app/javascript/dashboard/store/modules/specs/conversationStats/mutations.spec.js index e49d938e3..e625eb13c 100644 --- a/app/javascript/dashboard/store/modules/specs/conversationStats/mutations.spec.js +++ b/app/javascript/dashboard/store/modules/specs/conversationStats/mutations.spec.js @@ -14,6 +14,7 @@ describe('#mutations', () => { mineCount: 1, unAssignedCount: 1, allCount: 2, + updatedOn: expect.any(Date), }); }); });