Reduce polling (#2465)

* Move profile and preference polling to polls-on-foreground

* Refetch prefs on feeds screen refresh since polling no longer occurs

* Reduce notifications polling by 50% if there's already an unread

* Disable feed polling if we know we have content

* Disable the hard refresh after 1 hour in case it's the cause of the random feed refresh bug

* Fix types
This commit is contained in:
Paul Frazee 2024-01-10 22:27:14 -08:00 committed by GitHub
parent 0442dcc1a0
commit 7ab4be6f7d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 79 additions and 14 deletions

View file

@ -35,4 +35,5 @@ export interface CachedFeedPage {
usableInFeed: boolean
syncedAt: Date
data: FeedPage | undefined
unreadCount: number
}

View file

@ -25,7 +25,10 @@ type StateContext = string
interface ApiContext {
markAllRead: () => Promise<void>
checkUnread: (opts?: {invalidate?: boolean}) => Promise<void>
checkUnread: (opts?: {
invalidate?: boolean
isPoll?: boolean
}) => Promise<void>
getCachedUnreadPage: () => FeedPage | undefined
}
@ -50,6 +53,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
usableInFeed: false,
syncedAt: new Date(),
data: undefined,
unreadCount: 0,
})
// periodic sync
@ -58,7 +62,10 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
return
}
checkUnreadRef.current() // fire on init
const interval = setInterval(checkUnreadRef.current, UPDATE_INTERVAL)
const interval = setInterval(
() => checkUnreadRef.current?.({isPoll: true}),
UPDATE_INTERVAL,
)
return () => clearInterval(interval)
}, [hasSession])
@ -69,6 +76,12 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
usableInFeed: false,
syncedAt: new Date(),
data: undefined,
unreadCount:
data.event === '30+'
? 30
: data.event === ''
? 0
: parseInt(data.event, 10) || 1,
}
setNumUnread(data.event)
}
@ -95,13 +108,24 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
}
},
async checkUnread({invalidate}: {invalidate?: boolean} = {}) {
async checkUnread({
invalidate,
isPoll,
}: {invalidate?: boolean; isPoll?: boolean} = {}) {
try {
if (!getAgent().session) return
if (AppState.currentState !== 'active') {
return
}
// reduce polling if unread count is set
if (isPoll && cacheRef.current?.unreadCount !== 0) {
// if hit 30+ then don't poll, otherwise reduce polling by 50%
if (cacheRef.current?.unreadCount >= 30 || Math.random() >= 0.5) {
return
}
}
// count
const page = await fetchPage({
cursor: undefined,
@ -133,6 +157,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
usableInFeed: !!invalidate, // will be used immediately
data: page,
syncedAt: !lastIndexed || now > lastIndexed ? now : lastIndexed,
unreadCount,
}
// update & broadcast

View file

@ -31,7 +31,7 @@ export function usePreferencesQuery() {
return useQuery({
staleTime: STALE.SECONDS.FIFTEEN,
structuralSharing: true,
refetchInterval: STALE.SECONDS.FIFTEEN,
refetchOnWindowFocus: true,
queryKey: preferencesQueryKey,
queryFn: async () => {
const agent = getAgent()

View file

@ -35,7 +35,7 @@ export function useProfileQuery({did}: {did: string | undefined}) {
// if you remove it, the UI infinite-loops
// -prf
staleTime: isCurrentAccount ? STALE.SECONDS.THIRTY : STALE.MINUTES.FIVE,
refetchInterval: STALE.MINUTES.FIVE,
refetchOnWindowFocus: true,
queryKey: RQKEY(did || ''),
queryFn: async () => {
const res = await getAgent().getProfile({actor: did || ''})