-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[lib] Create a queue and use it to process queued operations
Summary: It is possible that we need an updated state when processing the next operation, so we need to make sure that the new state is propagated. https://linear.app/comm/issue/ENG-9470/mitigate-risks-of-effects-running-on-outdated-data Test Plan: Tested that this diff doesn't introduce a regression: 1. Receiving an edit entry operation before create entry 2. Receiving a change thread settings operation before create thread 3. Receiving a change thread subscription before adding as a member Each of these produces the correct state and clears the Redux queue. Also tested that we have a bug that this diff fixes. Created three operations that were processed in the following order: 1. Change thread name at timestamp T+1 2. Change thread description at T+1 3. Create thread at T Before this diff, there were robotexts displayed for each of these, but the thread name wasn't changed. After this diff both thread name and description are updated. Reviewers: kamil, ashoat Reviewed By: ashoat Differential Revision: https://phab.comm.dev/D13572
- Loading branch information
Showing
2 changed files
with
142 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// @flow | ||
|
||
import * as React from 'react'; | ||
|
||
type MessageQueueHook<T> = { | ||
+enqueue: (items: $ReadOnlyArray<T>) => void, | ||
}; | ||
|
||
function useActionsQueue<T>( | ||
performAction: (item: T) => mixed | Promise<mixed>, | ||
): MessageQueueHook<T> { | ||
const [queue, setQueue] = React.useState<$ReadOnlyArray<T>>([]); | ||
const isProcessing = React.useRef(false); | ||
|
||
const process = React.useCallback( | ||
async (action: T) => { | ||
isProcessing.current = true; | ||
try { | ||
await performAction(action); | ||
} finally { | ||
isProcessing.current = false; | ||
setQueue(currentQueue => currentQueue.slice(1)); | ||
} | ||
}, | ||
[performAction], | ||
); | ||
|
||
const enqueue = React.useCallback( | ||
(items: $ReadOnlyArray<T>) => | ||
setQueue(prevQueue => [...prevQueue, ...items]), | ||
[], | ||
); | ||
|
||
React.useEffect(() => { | ||
if (isProcessing.current || queue.length === 0) { | ||
return; | ||
} | ||
void process(queue[0]); | ||
}, [process, queue]); | ||
|
||
return { enqueue }; | ||
} | ||
|
||
export { useActionsQueue }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters