feat: Add debounce for meta query (#11195)
This PR combines the approaches in https://github.com/chatwoot/chatwoot/pull/11190 and https://github.com/chatwoot/chatwoot/pull/11187 to debounce the meta request with a max wait time of 2.5 seconds With 500 concurrent users, the theoretical limit with this is 720K requests per minute, if all of them continuously receive websocket events. The max wait of 2.5 seconds is still very generous, and we can easily make it 2 seconds for smaller accounts and 5 seconds for larger accounts. ```js const debouncedFetchMetaData = debounce(fetchMetaData, 500, false, 200); const longDebouncedFetchMetaData = debounce(fetchMetaData, 500, false, 5000); export const actions = { get: async ({ commit, state: $state }, params) => { if ($state.allCount > 100) { longDebouncedFetchMetaData(commit, params); } else { debouncedFetchMetaData(commit, params); } }, set({ commit }, meta) { commit(types.SET_CONV_TAB_META, meta); }, }; ``` Related Utils PR: https://github.com/chatwoot/utils/pull/49 Here's the debounce in action <img width="934" alt="image" src="https://github.com/user-attachments/assets/5265a108-9c64-4488-9b4c-2e0d06aadc50" /> --------- Co-authored-by: Pranav <pranavrajs@gmail.com>
This commit is contained in:
@@ -6,22 +6,41 @@ const commit = vi.fn();
|
||||
global.axios = axios;
|
||||
vi.mock('axios');
|
||||
|
||||
vi.mock('@chatwoot/utils', () => ({
|
||||
debounce: vi.fn(fn => {
|
||||
return fn;
|
||||
}),
|
||||
}));
|
||||
|
||||
describe('#actions', () => {
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers(); // Set up fake timers
|
||||
commit.mockClear();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers(); // Reset to real timers after each test
|
||||
});
|
||||
|
||||
describe('#get', () => {
|
||||
it('sends correct mutations if API is success', async () => {
|
||||
axios.get.mockResolvedValue({ data: { meta: { mine_count: 1 } } });
|
||||
await actions.get(
|
||||
{ commit, state: { updatedOn: null } },
|
||||
actions.get(
|
||||
{ commit, state: { allCount: 0 } },
|
||||
{ inboxId: 1, assigneeTpe: 'me', status: 'open' }
|
||||
);
|
||||
|
||||
await vi.runAllTimersAsync();
|
||||
await vi.waitFor(() => expect(commit).toHaveBeenCalled());
|
||||
|
||||
expect(commit.mock.calls).toEqual([
|
||||
[types.default.SET_CONV_TAB_META, { mine_count: 1 }],
|
||||
]);
|
||||
});
|
||||
it('sends correct actions if API is error', async () => {
|
||||
axios.get.mockRejectedValue({ message: 'Incorrect header' });
|
||||
await actions.get(
|
||||
{ commit, state: { updatedOn: null } },
|
||||
actions.get(
|
||||
{ commit, state: { allCount: 0 } },
|
||||
{ inboxId: 1, assigneeTpe: 'me', status: 'open' }
|
||||
);
|
||||
expect(commit.mock.calls).toEqual([]);
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import ConversationMetaThrottleManager from 'dashboard/helper/ConversationMetaThrottleManager';
|
||||
import { shouldThrottle } from '../../conversationStats';
|
||||
|
||||
vi.mock('dashboard/helper/ConversationMetaThrottleManager', () => ({
|
||||
default: {
|
||||
shouldThrottle: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('shouldThrottle', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('uses normal threshold for accounts with 100 or fewer conversations', () => {
|
||||
shouldThrottle(100);
|
||||
expect(ConversationMetaThrottleManager.shouldThrottle).toHaveBeenCalledWith(
|
||||
2000
|
||||
);
|
||||
});
|
||||
|
||||
it('uses large account threshold for accounts with more than 100 conversations', () => {
|
||||
shouldThrottle(101);
|
||||
expect(ConversationMetaThrottleManager.shouldThrottle).toHaveBeenCalledWith(
|
||||
10000
|
||||
);
|
||||
});
|
||||
|
||||
it('returns the throttle value from ConversationMetaThrottleManager', () => {
|
||||
ConversationMetaThrottleManager.shouldThrottle.mockReturnValue(true);
|
||||
expect(shouldThrottle(50)).toBe(true);
|
||||
|
||||
ConversationMetaThrottleManager.shouldThrottle.mockReturnValue(false);
|
||||
expect(shouldThrottle(150)).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user