From 03dbb078a931d8b6bc2c5a28a5dfa41900d97b31 Mon Sep 17 00:00:00 2001 From: Foysal Ahamed Date: Wed, 11 Sep 2024 18:23:13 +0200 Subject: [PATCH] :sparkles: Recursively load queue pages if current page is empty (#185) * :sparkles: Recursively load queue pages if current page is empty * :rotating_light: Add types for function signature * :lock: Make sure we don't infinitely call recursive loop --- app/reports/page-content.tsx | 69 ++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/app/reports/page-content.tsx b/app/reports/page-content.tsx index 0247557..291867d 100644 --- a/app/reports/page-content.tsx +++ b/app/reports/page-content.tsx @@ -8,6 +8,7 @@ import { } from 'next/navigation' import { useInfiniteQuery } from '@tanstack/react-query' import { + Agent, AtUri, ToolsOzoneModerationDefs, ToolsOzoneModerationEmitEvent, @@ -356,29 +357,53 @@ function useModerationQueueQuery() { } }) - const { data } = - await labelerAgent.api.tools.ozone.moderation.queryStatuses({ - limit: 50, - includeMuted: true, - ...queryParams, - }) - - const queueDivider = QUEUE_NAMES.length - const queueIndex = QUEUE_NAMES.indexOf(queueName ?? '') - const statusesInQueue = queueName - ? data.subjectStatuses.filter((status) => { - const subjectDid = - status.subject.$type === 'com.atproto.admin.defs#repoRef' - ? status.subject.did - : new AtUri(`${status.subject.uri}`).host - const queueDeciderCharCode = - `${subjectDid}`.split(':').pop()?.charCodeAt(0) || 0 - return queueDeciderCharCode % queueDivider === queueIndex - }) - : data.subjectStatuses - - return { cursor: data.cursor, subjectStatuses: statusesInQueue } + return getQueueItems(labelerAgent, queryParams, queueName) }, getNextPageParam: (lastPage) => lastPage.cursor, }) } + +const getQueueItems = async ( + labelerAgent: Agent, + queryParams: ToolsOzoneModerationQueryStatuses.QueryParams, + queueName: string | null, + attempt = 0, +) => { + const pageSize = 50 + const { data } = await labelerAgent.tools.ozone.moderation.queryStatuses({ + limit: pageSize, + includeMuted: true, + ...queryParams, + }) + + const queueDivider = QUEUE_NAMES.length + const queueIndex = QUEUE_NAMES.indexOf(queueName ?? '') + const statusesInQueue = queueName + ? data.subjectStatuses.filter((status) => { + const subjectDid = + status.subject.$type === 'com.atproto.admin.defs#repoRef' + ? status.subject.did + : new AtUri(`${status.subject.uri}`).host + const queueDeciderCharCode = + `${subjectDid}`.split(':').pop()?.charCodeAt(0) || 0 + return queueDeciderCharCode % queueDivider === queueIndex + }) + : data.subjectStatuses + + // This is a recursive call to get items in queue if the current page + // gives us less than full page size and there are more items to fetch + // also, use a circuit breaker to make sure we never accidentally call this more than 10 times + if (statusesInQueue.length === 0 && data.cursor && attempt < 10) { + return getQueueItems( + labelerAgent, + { + ...queryParams, + cursor: data.cursor, + }, + queueName, + ++attempt, + ) + } + + return { cursor: data.cursor, subjectStatuses: statusesInQueue } +}