-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Queue fixes #250
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Queue fixes #250
Changes from all commits
9111eb0
a646d72
b58f6f6
cfcd5e4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,28 +1,22 @@ | ||||||||||||||||||||||||||||||||||
| "use client"; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| import { useAtom } from "jotai"; | ||||||||||||||||||||||||||||||||||
| import { useAtomValue } from "jotai"; | ||||||||||||||||||||||||||||||||||
| import { useEffect } from "react"; | ||||||||||||||||||||||||||||||||||
| import { processQueue, queueAtoms } from "@/store/archive-queue"; | ||||||||||||||||||||||||||||||||||
| import { processQueue, queueAtom } from "@/store/archive-queue"; | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| function useInitializeQueues() { | ||||||||||||||||||||||||||||||||||
| const [archiveQueue] = useAtom(queueAtoms.archive); | ||||||||||||||||||||||||||||||||||
| const [deleteQueue] = useAtom(queueAtoms.delete); | ||||||||||||||||||||||||||||||||||
| const [markReadQueue] = useAtom(queueAtoms.markRead); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| useEffect(() => { | ||||||||||||||||||||||||||||||||||
| const threadIds = Object.keys(archiveQueue.activeThreadIds || {}); | ||||||||||||||||||||||||||||||||||
| if (threadIds.length) processQueue("archive", threadIds); | ||||||||||||||||||||||||||||||||||
| }, [archiveQueue]); | ||||||||||||||||||||||||||||||||||
| let isInitialized = false; | ||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Avoid using module-scoped variables for component state Defining Consider using the Apply this diff to refactor: - let isInitialized = false;
function useInitializeQueues() {
+ const isInitialized = useRef(false);
const queueState = useAtomValue(queueAtom);
useEffect(() => {
- if (!isInitialized) {
- isInitialized = true;
+ if (!isInitialized.current) {
+ isInitialized.current = true;
if (queueState.activeThreads) {
processQueue({ threads: queueState.activeThreads });
}
}
}, [queueState.activeThreads]);
}📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| useEffect(() => { | ||||||||||||||||||||||||||||||||||
| const threadIds = Object.keys(deleteQueue.activeThreadIds || {}); | ||||||||||||||||||||||||||||||||||
| if (threadIds.length) processQueue("delete", threadIds); | ||||||||||||||||||||||||||||||||||
| }, [deleteQueue]); | ||||||||||||||||||||||||||||||||||
| function useInitializeQueues() { | ||||||||||||||||||||||||||||||||||
| const queueState = useAtomValue(queueAtom); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| useEffect(() => { | ||||||||||||||||||||||||||||||||||
| const threadIds = Object.keys(markReadQueue.activeThreadIds || {}); | ||||||||||||||||||||||||||||||||||
| if (threadIds.length) processQueue("markRead", threadIds); | ||||||||||||||||||||||||||||||||||
| }, [markReadQueue]); | ||||||||||||||||||||||||||||||||||
| if (!isInitialized) { | ||||||||||||||||||||||||||||||||||
| isInitialized = true; | ||||||||||||||||||||||||||||||||||
| if (queueState.activeThreads) { | ||||||||||||||||||||||||||||||||||
| processQueue({ threads: queueState.activeThreads }); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| }, [queueState.activeThreads]); | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+13
to
+19
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Ensure the effect responds to changes in The current If the intention is to process the queue whenever Apply this diff to adjust the logic: useEffect(() => {
- if (!isInitialized.current) {
- isInitialized.current = true;
if (queueState.activeThreads) {
processQueue({ threads: queueState.activeThreads });
}
- }
}, [queueState.activeThreads]);Alternatively, if the effect should run only once, remove useEffect(() => {
if (!isInitialized.current) {
isInitialized.current = true;
if (queueState.activeThreads) {
processQueue({ threads: queueState.activeThreads });
}
}
- }, [queueState.activeThreads]);
+ }, []);📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| export function QueueInitializer() { | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,103 +1,146 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||
| import { atomWithStorage, createJSONStorage } from "jotai/utils"; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import pRetry from "p-retry"; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import { jotaiStore } from "@/store"; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import { emailActionQueue } from "@/utils/queue/email-action-queue"; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||||||||||||||||||||
| archiveThreadAction, | ||||||||||||||||||||||||||||||||||||||||||||||||
| trashThreadAction, | ||||||||||||||||||||||||||||||||||||||||||||||||
| markReadThreadAction, | ||||||||||||||||||||||||||||||||||||||||||||||||
| } from "@/utils/actions/mail"; | ||||||||||||||||||||||||||||||||||||||||||||||||
| import { isActionError, ServerActionResponse } from "@/utils/error"; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Use 'import type' for type-only imports to optimize build output The Apply this diff to adjust the import: -import { isActionError, ServerActionResponse } from "@/utils/error";
+import { isActionError } from "@/utils/error";
+import type { ServerActionResponse } from "@/utils/error";📝 Committable suggestion
Suggested change
🧰 Tools🪛 Biome
|
||||||||||||||||||||||||||||||||||||||||||||||||
| import { exponentialBackoff, sleep } from "@/utils/sleep"; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| type QueueType = "archive" | "delete" | "markRead"; | ||||||||||||||||||||||||||||||||||||||||||||||||
| type ActionType = "archive" | "delete" | "markRead"; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| type QueueItem = { | ||||||||||||||||||||||||||||||||||||||||||||||||
| threadId: string; | ||||||||||||||||||||||||||||||||||||||||||||||||
| actionType: ActionType; | ||||||||||||||||||||||||||||||||||||||||||||||||
| labelId?: string; | ||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| type QueueState = { | ||||||||||||||||||||||||||||||||||||||||||||||||
| activeThreadIds: Record<string, boolean>; | ||||||||||||||||||||||||||||||||||||||||||||||||
| activeThreads: Record<`${ActionType}-${string}`, QueueItem>; | ||||||||||||||||||||||||||||||||||||||||||||||||
| totalThreads: number; | ||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| function getInitialState(): QueueState { | ||||||||||||||||||||||||||||||||||||||||||||||||
| return { activeThreadIds: {}, totalThreads: 0 }; | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| // some users were somehow getting null for activeThreadIds, this should fix it | ||||||||||||||||||||||||||||||||||||||||||||||||
| // some users were somehow getting null for activeThreads, this should fix it | ||||||||||||||||||||||||||||||||||||||||||||||||
| const createStorage = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||
| if (typeof window === "undefined") return; | ||||||||||||||||||||||||||||||||||||||||||||||||
| const storage = createJSONStorage<QueueState>(() => localStorage); | ||||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||||
| ...storage, | ||||||||||||||||||||||||||||||||||||||||||||||||
| getItem: (key: string, initialValue: QueueState) => { | ||||||||||||||||||||||||||||||||||||||||||||||||
| const storedValue = storage.getItem(key, initialValue); | ||||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||||
| activeThreadIds: storedValue.activeThreadIds || {}, | ||||||||||||||||||||||||||||||||||||||||||||||||
| activeThreads: storedValue.activeThreads || {}, | ||||||||||||||||||||||||||||||||||||||||||||||||
| totalThreads: storedValue.totalThreads || 0, | ||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| // Create atoms with localStorage persistence for each queue type | ||||||||||||||||||||||||||||||||||||||||||||||||
| export const queueAtoms = { | ||||||||||||||||||||||||||||||||||||||||||||||||
| archive: atomWithStorage("archiveQueue", getInitialState(), createStorage()), | ||||||||||||||||||||||||||||||||||||||||||||||||
| delete: atomWithStorage("deleteQueue", getInitialState(), createStorage()), | ||||||||||||||||||||||||||||||||||||||||||||||||
| markRead: atomWithStorage( | ||||||||||||||||||||||||||||||||||||||||||||||||
| "markReadQueue", | ||||||||||||||||||||||||||||||||||||||||||||||||
| getInitialState(), | ||||||||||||||||||||||||||||||||||||||||||||||||
| createStorage(), | ||||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||
| // Create atoms with localStorage persistence | ||||||||||||||||||||||||||||||||||||||||||||||||
| export const queueAtom = atomWithStorage( | ||||||||||||||||||||||||||||||||||||||||||||||||
| "gmailActionQueue", | ||||||||||||||||||||||||||||||||||||||||||||||||
| { activeThreads: {}, totalThreads: 0 }, | ||||||||||||||||||||||||||||||||||||||||||||||||
| createStorage(), | ||||||||||||||||||||||||||||||||||||||||||||||||
| { getOnInit: true }, | ||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| type ActionFunction = (threadId: string, ...args: any[]) => Promise<any>; | ||||||||||||||||||||||||||||||||||||||||||||||||
| type ActionFunction = ( | ||||||||||||||||||||||||||||||||||||||||||||||||
| threadId: string, | ||||||||||||||||||||||||||||||||||||||||||||||||
| labelId?: string, | ||||||||||||||||||||||||||||||||||||||||||||||||
| ) => Promise<ServerActionResponse<{}>>; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid using '{}' as a type; specify the correct type or use 'void' Using Apply this diff to fix the type: -) => Promise<ServerActionResponse<{}>>;
+) => Promise<ServerActionResponse<void>>;📝 Committable suggestion
Suggested change
🧰 Tools🪛 Biome
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| const actionMap: Record<QueueType, ActionFunction> = { | ||||||||||||||||||||||||||||||||||||||||||||||||
| archive: archiveThreadAction, | ||||||||||||||||||||||||||||||||||||||||||||||||
| const actionMap: Record<ActionType, ActionFunction> = { | ||||||||||||||||||||||||||||||||||||||||||||||||
| archive: (threadId: string, labelId?: string) => | ||||||||||||||||||||||||||||||||||||||||||||||||
| archiveThreadAction(threadId, labelId), | ||||||||||||||||||||||||||||||||||||||||||||||||
| delete: trashThreadAction, | ||||||||||||||||||||||||||||||||||||||||||||||||
| markRead: (threadId: string) => markReadThreadAction(threadId, true), | ||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| export const addThreadsToQueue = ( | ||||||||||||||||||||||||||||||||||||||||||||||||
| queueType: QueueType, | ||||||||||||||||||||||||||||||||||||||||||||||||
| threadIds: string[], | ||||||||||||||||||||||||||||||||||||||||||||||||
| refetch?: () => void, | ||||||||||||||||||||||||||||||||||||||||||||||||
| ) => { | ||||||||||||||||||||||||||||||||||||||||||||||||
| const queueAtom = queueAtoms[queueType]; | ||||||||||||||||||||||||||||||||||||||||||||||||
| export const addThreadsToQueue = ({ | ||||||||||||||||||||||||||||||||||||||||||||||||
| actionType, | ||||||||||||||||||||||||||||||||||||||||||||||||
| threadIds, | ||||||||||||||||||||||||||||||||||||||||||||||||
| labelId, | ||||||||||||||||||||||||||||||||||||||||||||||||
| refetch, | ||||||||||||||||||||||||||||||||||||||||||||||||
| }: { | ||||||||||||||||||||||||||||||||||||||||||||||||
| actionType: ActionType; | ||||||||||||||||||||||||||||||||||||||||||||||||
| threadIds: string[]; | ||||||||||||||||||||||||||||||||||||||||||||||||
| labelId?: string; | ||||||||||||||||||||||||||||||||||||||||||||||||
| refetch?: () => void; | ||||||||||||||||||||||||||||||||||||||||||||||||
| }) => { | ||||||||||||||||||||||||||||||||||||||||||||||||
| const threads = Object.fromEntries( | ||||||||||||||||||||||||||||||||||||||||||||||||
| threadIds.map((threadId) => [ | ||||||||||||||||||||||||||||||||||||||||||||||||
| `${actionType}-${threadId}`, | ||||||||||||||||||||||||||||||||||||||||||||||||
| { threadId, actionType, labelId }, | ||||||||||||||||||||||||||||||||||||||||||||||||
| ]), | ||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| jotaiStore.set(queueAtom, (prev) => ({ | ||||||||||||||||||||||||||||||||||||||||||||||||
| activeThreadIds: { | ||||||||||||||||||||||||||||||||||||||||||||||||
| ...prev.activeThreadIds, | ||||||||||||||||||||||||||||||||||||||||||||||||
| ...Object.fromEntries(threadIds.map((id) => [id, true])), | ||||||||||||||||||||||||||||||||||||||||||||||||
| activeThreads: { | ||||||||||||||||||||||||||||||||||||||||||||||||
| ...prev.activeThreads, | ||||||||||||||||||||||||||||||||||||||||||||||||
| ...threads, | ||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||
| totalThreads: prev.totalThreads + threadIds.length, | ||||||||||||||||||||||||||||||||||||||||||||||||
| totalThreads: prev.totalThreads + Object.keys(threads).length, | ||||||||||||||||||||||||||||||||||||||||||||||||
| })); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| processQueue(queueType, threadIds, refetch); | ||||||||||||||||||||||||||||||||||||||||||||||||
| processQueue({ threads, refetch }); | ||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| export function processQueue( | ||||||||||||||||||||||||||||||||||||||||||||||||
| queueType: QueueType, | ||||||||||||||||||||||||||||||||||||||||||||||||
| threadIds: string[], | ||||||||||||||||||||||||||||||||||||||||||||||||
| refetch?: () => void, | ||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| const queueAtom = queueAtoms[queueType]; | ||||||||||||||||||||||||||||||||||||||||||||||||
| const action = actionMap[queueType]; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| export function processQueue({ | ||||||||||||||||||||||||||||||||||||||||||||||||
| threads, | ||||||||||||||||||||||||||||||||||||||||||||||||
| refetch, | ||||||||||||||||||||||||||||||||||||||||||||||||
| }: { | ||||||||||||||||||||||||||||||||||||||||||||||||
| threads: Record<string, QueueItem>; | ||||||||||||||||||||||||||||||||||||||||||||||||
| refetch?: () => void; | ||||||||||||||||||||||||||||||||||||||||||||||||
| }) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| emailActionQueue.addAll( | ||||||||||||||||||||||||||||||||||||||||||||||||
| threadIds.map((threadId) => async () => { | ||||||||||||||||||||||||||||||||||||||||||||||||
| await action(threadId); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| // remove completed thread from activeThreadIds | ||||||||||||||||||||||||||||||||||||||||||||||||
| jotaiStore.set(queueAtom, (prev) => { | ||||||||||||||||||||||||||||||||||||||||||||||||
| const { [threadId]: _, ...remainingThreads } = prev.activeThreadIds; | ||||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||||
| ...prev, | ||||||||||||||||||||||||||||||||||||||||||||||||
| activeThreadIds: remainingThreads, | ||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| refetch?.(); | ||||||||||||||||||||||||||||||||||||||||||||||||
| }), | ||||||||||||||||||||||||||||||||||||||||||||||||
| Object.entries(threads).map( | ||||||||||||||||||||||||||||||||||||||||||||||||
| ([_key, { threadId, actionType, labelId }]) => | ||||||||||||||||||||||||||||||||||||||||||||||||
| async () => { | ||||||||||||||||||||||||||||||||||||||||||||||||
| await pRetry( | ||||||||||||||||||||||||||||||||||||||||||||||||
| async (attemptCount) => { | ||||||||||||||||||||||||||||||||||||||||||||||||
| console.log( | ||||||||||||||||||||||||||||||||||||||||||||||||
| `Queue: ${actionType}. Processing ${threadId}` + | ||||||||||||||||||||||||||||||||||||||||||||||||
| (attemptCount > 1 ? ` (attempt ${attemptCount})` : ""), | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+105
to
+106
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Use a single template literal instead of string concatenation Combining the template literals into a single expression enhances readability and avoids unnecessary string concatenation. Apply this diff to fix the issue: -`Queue: ${actionType}. Processing ${threadId}` +
- (attemptCount > 1 ? ` (attempt ${attemptCount})` : ""),
+`Queue: ${actionType}. Processing ${threadId}${attemptCount > 1 ? ` (attempt ${attemptCount})` : ""}`,📝 Committable suggestion
Suggested change
🧰 Tools🪛 Biome
|
||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| const result = await actionMap[actionType](threadId, labelId); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ensure correct function signatures for action functions The Apply this diff to conditionally pass -const result = await actionMap[actionType](threadId, labelId);
+const actionFn = actionMap[actionType];
+const result =
+ actionType === "archive"
+ ? await actionFn(threadId, labelId)
+ : await actionFn(threadId);Alternatively, adjust the 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| // when Gmail API returns a rate limit error, throw an error so it can be retried | ||||||||||||||||||||||||||||||||||||||||||||||||
| if (isActionError(result)) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| await sleep(exponentialBackoff(attemptCount, 1_000)); | ||||||||||||||||||||||||||||||||||||||||||||||||
| throw new Error(result.error); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| refetch?.(); | ||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||
| { retries: 3 }, | ||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| // remove completed thread from activeThreads | ||||||||||||||||||||||||||||||||||||||||||||||||
| jotaiStore.set(queueAtom, (prev) => { | ||||||||||||||||||||||||||||||||||||||||||||||||
| const remainingThreads = Object.fromEntries( | ||||||||||||||||||||||||||||||||||||||||||||||||
| Object.entries(prev.activeThreads).filter( | ||||||||||||||||||||||||||||||||||||||||||||||||
| ([_key, value]) => | ||||||||||||||||||||||||||||||||||||||||||||||||
| !( | ||||||||||||||||||||||||||||||||||||||||||||||||
| value.threadId === threadId && | ||||||||||||||||||||||||||||||||||||||||||||||||
| value.actionType === actionType | ||||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||||
| ...prev, | ||||||||||||||||||||||||||||||||||||||||||||||||
| activeThreads: remainingThreads, | ||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+122
to
+137
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Optimize removal of completed threads from 'activeThreads' using the key directly Currently, removing completed threads involves filtering over all entries, which can be inefficient. Since keys are constructed as Apply this diff to optimize the removal: -jotaiStore.set(queueAtom, (prev) => {
- const remainingThreads = Object.fromEntries(
- Object.entries(prev.activeThreads).filter(
- ([_key, value]) =>
- !(
- value.threadId === threadId &&
- value.actionType === actionType
- ),
- ),
- );
- return {
- ...prev,
- activeThreads: remainingThreads,
- };
-});
+jotaiStore.set(queueAtom, (prev) => {
+ const { [`${actionType}-${threadId}`]: _, ...remainingThreads } = prev.activeThreads;
+ return {
+ ...prev,
+ activeThreads: remainingThreads,
+ };
+});📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| export const resetTotalThreads = (queueType: QueueType) => { | ||||||||||||||||||||||||||||||||||||||||||||||||
| const queueAtom = queueAtoms[queueType]; | ||||||||||||||||||||||||||||||||||||||||||||||||
| export const resetTotalThreads = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||
| jotaiStore.set(queueAtom, (prev) => ({ | ||||||||||||||||||||||||||||||||||||||||||||||||
| ...prev, | ||||||||||||||||||||||||||||||||||||||||||||||||
| totalThreads: 0, | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Issues found with import paths.
The import path for
resetTotalThreadsis invalid;store/archive-queue.tsdoes not exist or does not exportresetTotalThreads.🔗 Analysis chain
LGTM! Verify import paths.
The changes to the import statements look good. The addition of
memofor component optimization and the reorganization of imports improve code structure and potential performance.Let's verify the new import paths:
Also applies to: 5-5
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
Length of output: 388