diff --git a/apps/client/src/common/hooks-query/useCustomFields.ts b/apps/client/src/common/hooks-query/useCustomFields.ts index 72d05762a..36a087fb9 100644 --- a/apps/client/src/common/hooks-query/useCustomFields.ts +++ b/apps/client/src/common/hooks-query/useCustomFields.ts @@ -1,7 +1,7 @@ import { useQuery } from '@tanstack/react-query'; import { CustomFields } from 'ontime-types'; -import { queryRefetchInterval } from '../../ontimeConfig'; +import { queryRefetchIntervalSlow } from '../../ontimeConfig'; import { CUSTOM_FIELDS } from '../api/constants'; import { getCustomFields } from '../api/customFields'; @@ -14,7 +14,7 @@ export default function useCustomFields() { placeholderData: (previousData, _previousQuery) => previousData, retry: 5, retryDelay: (attempt) => attempt * 2500, - refetchInterval: queryRefetchInterval, + refetchInterval: queryRefetchIntervalSlow, networkMode: 'always', }); diff --git a/apps/client/src/common/hooks-query/useRundown.ts b/apps/client/src/common/hooks-query/useRundown.ts index dd894e2e4..8c2c2d6a4 100644 --- a/apps/client/src/common/hooks-query/useRundown.ts +++ b/apps/client/src/common/hooks-query/useRundown.ts @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'; import { useQuery } from '@tanstack/react-query'; import { NormalisedRundown, OntimeRundown, RundownCached } from 'ontime-types'; -import { queryRefetchInterval } from '../../ontimeConfig'; +import { queryRefetchIntervalSlow } from '../../ontimeConfig'; import { RUNDOWN } from '../api/constants'; import { fetchNormalisedRundown } from '../api/rundown'; @@ -16,7 +16,7 @@ export default function useRundown() { placeholderData: (previousData, _previousQuery) => previousData, retry: 5, retryDelay: (attempt) => attempt * 2500, - refetchInterval: queryRefetchInterval, + refetchInterval: queryRefetchIntervalSlow, networkMode: 'always', }); return { data: data ?? cachedRundownPlaceholder, status, isError, refetch, isFetching }; diff --git a/apps/client/src/common/utils/socket.ts b/apps/client/src/common/utils/socket.ts index 679b5d8d9..cf23e9812 100644 --- a/apps/client/src/common/utils/socket.ts +++ b/apps/client/src/common/utils/socket.ts @@ -1,6 +1,6 @@ -import { Log, RuntimeStore } from 'ontime-types'; +import { Log, RundownCached, RuntimeStore } from 'ontime-types'; -import { CLIENT_LIST, isProduction, RUNTIME, websocketUrl } from '../api/constants'; +import { CLIENT_LIST, CUSTOM_FIELDS, isProduction, RUNDOWN, RUNTIME, websocketUrl } from '../api/constants'; import { ontimeQueryClient } from '../queryClient'; import { getClientId, @@ -176,6 +176,17 @@ export const connectSocket = () => { updateDevTools({ auxtimer1: payload }); break; } + case 'ontime-refetch': { + // the refetch message signals that the rundown has changed in the server side + const { revision } = payload; + const currentRevision = ontimeQueryClient.getQueryData(RUNDOWN)?.revision ?? -1; + + if (revision > currentRevision) { + ontimeQueryClient.invalidateQueries({ queryKey: RUNDOWN }); + ontimeQueryClient.invalidateQueries({ queryKey: CUSTOM_FIELDS }); + } + break; + } } } catch (_) { // ignore unhandled diff --git a/apps/client/src/ontimeConfig.ts b/apps/client/src/ontimeConfig.ts index fcc7c2eae..760d8f306 100644 --- a/apps/client/src/ontimeConfig.ts +++ b/apps/client/src/ontimeConfig.ts @@ -2,5 +2,5 @@ export const tooltipDelaySlow = 1000; export const tooltipDelayMid = 500; export const tooltipDelayFast = 300; -export const queryRefetchInterval = 10000; -export const queryRefetchIntervalSlow = 30000; +export const queryRefetchInterval = 10000; // 10 seconds +export const queryRefetchIntervalSlow = 30000; // 30 seconds diff --git a/apps/server/src/services/rundown-service/RundownService.ts b/apps/server/src/services/rundown-service/RundownService.ts index 829b4928b..000b37468 100644 --- a/apps/server/src/services/rundown-service/RundownService.ts +++ b/apps/server/src/services/rundown-service/RundownService.ts @@ -247,7 +247,11 @@ function notifyChanges(options: { timer?: boolean | string[]; external?: boolean if (options.external) { // advice socket subscribers of change - sendRefetch(Array.isArray(options.timer) ? options.timer : undefined); + const payload = { + changes: Array.isArray(options.timer) ? options.timer : undefined, + revision: cache.getMetadata().revision, + }; + sendRefetch(payload); } } diff --git a/apps/server/src/services/rundown-service/rundownCache.ts b/apps/server/src/services/rundown-service/rundownCache.ts index 7583302c8..d42591bbd 100644 --- a/apps/server/src/services/rundown-service/rundownCache.ts +++ b/apps/server/src/services/rundown-service/rundownCache.ts @@ -215,6 +215,7 @@ export function getMetadata() { lastEnd, totalDelay, totalDuration, + revision, }; } @@ -243,6 +244,12 @@ export function mutateCache(mutation: MutatingFn) { const { newEvent, newRundown, didMutate } = mutation({ ...params, persistedRundown }); + // early return without calling side effects + if (!didMutate) { + isStale = false; + return { newEvent, newRundown, didMutate }; + } + revision = revision + 1; persistedRundown = newRundown;