diff --git a/src/hooks/useCertificate.ts b/src/hooks/useCertificate.ts index 99e78f321..a71c3ef70 100644 --- a/src/hooks/useCertificate.ts +++ b/src/hooks/useCertificate.ts @@ -28,6 +28,8 @@ type UseCertificateReturn = { }; const POLL_JITTER_MS = durationToMs(1, "seconds"); +/** A valid cert isn't going anywhere soon, so check on it far less often. */ +const VALID_POLL_INTERVAL_MS = durationToMs(30, "seconds"); export function useCertificate({ orgId, @@ -35,7 +37,7 @@ export function useCertificate({ fullDomain, initialCertValue, polling = false, - pollingInterval = 5000 + pollingInterval = durationToMs(5, "seconds") }: UseCertificateProps): UseCertificateReturn { const api = createApiClient(useEnvContext()); const queryClient = useQueryClient(); @@ -49,19 +51,19 @@ export function useCertificate({ const { data, isLoading, isError, refetch } = useQuery({ ...certQuery, enabled: Boolean(orgId && domainId && fullDomain), - // Add a small random offset to each tick. Without it, every row in a - // table would poll at the exact same instant, hitting the server in - // bursts instead of spreading the requests out. - refetchInterval: polling - ? () => - Math.max( - 1000, - Math.round( - pollingInterval + - (Math.random() * 2 - 1) * POLL_JITTER_MS - ) - ) - : false, + refetchInterval: (query) => { + if (!polling) return false; + const interval = + query.state.data?.status === "valid" + ? VALID_POLL_INTERVAL_MS + : pollingInterval; + // Add a small random offset to each tick. Without it, every row in + // a table would poll at the exact same instant, hitting the server + // in bursts instead of spreading the requests out. + // the requests will be jittered by less or more than 1s + const jitter = (Math.random() * 2 - 1) * POLL_JITTER_MS; + return Math.max(1000, interval + jitter); + }, // An explicit `null` is a real answer ("this domain has no certificate") // and is seeded like any other, so a server-prefetched row doesn't // refetch on mount. Only an omitted prop leaves the cache empty.