From 23204a3cdbb72ffde1fb04da5abcf84a4cf38064 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Sat, 22 Jun 2024 13:02:17 +0000 Subject: [PATCH] fix: avoid polling if token is not present and initialise polling when token changes --- packages/nc-gui/store/notification.ts | 55 ++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/packages/nc-gui/store/notification.ts b/packages/nc-gui/store/notification.ts index 403948bf48..dc2e7bd251 100644 --- a/packages/nc-gui/store/notification.ts +++ b/packages/nc-gui/store/notification.ts @@ -1,5 +1,7 @@ import { defineStore } from 'pinia' import type { NotificationType } from 'nocodb-sdk' +import axios, { type CancelTokenSource } from 'axios' +import { CancelToken } from 'axios' export const useNotification = defineStore('notificationStore', () => { const readNotifications = ref([]) @@ -16,9 +18,22 @@ export const useNotification = defineStore('notificationStore', () => { const { api, isLoading } = useApi() + const { token } = useGlobal() + + let timeOutId: number | null = null + + let cancelTokenSource: CancelTokenSource | null + const pollNotifications = async () => { try { - const res = await api.notification.poll() + if (!token.value) return + + // set up cancel token for polling to cancel when token changes/token is removed + cancelTokenSource = CancelToken.source() + + const res = await api.notification.poll({ + cancelToken: cancelTokenSource.token, + }) if (res.status === 'success') { if (notificationTab.value === 'unread') { @@ -28,10 +43,12 @@ export const useNotification = defineStore('notificationStore', () => { unreadCount.value = unreadCount.value + 1 } - setTimeout(pollNotifications, 0) + timeOutId = setTimeout(pollNotifications, 0) } catch (e) { + // If request is cancelled, do nothing + if (axios.isCancel(e)) return // If network error, retry after 2 seconds - setTimeout(pollNotifications, 2000) + timeOutId = setTimeout(pollNotifications, 2000) } } @@ -154,16 +171,44 @@ export const useNotification = defineStore('notificationStore', () => { } }) + // function to clear polling and cancel any pending requests + const clearPolling = () => { + if (timeOutId) { + clearTimeout(timeOutId) + timeOutId = null + } + cancelTokenSource?.cancel() + cancelTokenSource = null + } + const init = async () => { await Promise.allSettled([loadReadNotifications(), loadUnReadNotifications()]) // For playwright, polling will cause the test to hang indefinitely // as we wait for the networkidle event. So, we disable polling for playwright if (!(window as any).isPlaywright) { - pollNotifications() + clearPolling() + pollNotifications().catch((e) => console.log(e)) } } - onMounted(init) + // watch for token changes and re-init notifications if token changes + watch( + token, + async (newToken, oldToken) => { + try { + if (newToken && newToken !== oldToken) { + await init() + } else if (!newToken) { + clearPolling() + } + } catch (e) { + console.error(e) + } + }, + { + immediate: true, + }, + ) return { unreadNotifications,