Skip to content

Commit 171a4e6

Browse files
fix(ui): race condition when deleting a board and resetting selected/auto-add
We were checking the selected and auto-add board ids against the query cache to see if they still exist. If not, we reset. This only works if the query cache is updated by the time we do the check - race condition! We already have the board id from the query args, so there's no need to check the query cache - just compare the deleted board ID directly. Previously this file's several listeners were all in a single one and I had adapted/split its logic up a bit wonkily, introducing these problems.
1 parent e3a75a8 commit 171a4e6

File tree

1 file changed

+13
-19
lines changed

1 file changed

+13
-19
lines changed

invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/addArchivedOrDeletedBoardListener.ts

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,32 @@ import {
1010
import { boardsApi } from 'services/api/endpoints/boards';
1111
import { imagesApi } from 'services/api/endpoints/images';
1212

13+
// Type inference doesn't work for this if you inline it in the listener for some reason
14+
const matchAnyBoardDeleted = isAnyOf(
15+
imagesApi.endpoints.deleteBoard.matchFulfilled,
16+
imagesApi.endpoints.deleteBoardAndImages.matchFulfilled
17+
);
18+
1319
export const addArchivedOrDeletedBoardListener = (startAppListening: AppStartListening) => {
1420
/**
1521
* The auto-add board shouldn't be set to an archived board or deleted board. When we archive a board, delete
1622
* a board, or change a the archived board visibility flag, we may need to reset the auto-add board.
1723
*/
1824
startAppListening({
19-
matcher: isAnyOf(
20-
// If a board is deleted, we'll need to reset the auto-add board
21-
imagesApi.endpoints.deleteBoard.matchFulfilled,
22-
imagesApi.endpoints.deleteBoardAndImages.matchFulfilled
23-
),
25+
matcher: matchAnyBoardDeleted,
2426
effect: async (action, { dispatch, getState }) => {
2527
const state = getState();
26-
const queryArgs = selectListBoardsQueryArgs(state);
27-
const queryResult = boardsApi.endpoints.listAllBoards.select(queryArgs)(state);
28+
const deletedBoardId = action.meta.arg.originalArgs;
2829
const { autoAddBoardId, selectedBoardId } = state.gallery;
2930

30-
if (!queryResult.data) {
31-
return;
32-
}
33-
34-
if (!queryResult.data.find((board) => board.board_id === selectedBoardId)) {
31+
// If the deleted board was currently selected, we should reset the selected board to uncategorized
32+
if (deletedBoardId === selectedBoardId) {
3533
dispatch(boardIdSelected({ boardId: 'none' }));
3634
dispatch(galleryViewChanged('images'));
3735
}
38-
if (!queryResult.data.find((board) => board.board_id === autoAddBoardId)) {
36+
37+
// If the deleted board was selected for auto-add, we should reset the auto-add board to uncategorized
38+
if (deletedBoardId === autoAddBoardId) {
3939
dispatch(autoAddBoardIdChanged('none'));
4040
}
4141
},
@@ -46,14 +46,8 @@ export const addArchivedOrDeletedBoardListener = (startAppListening: AppStartLis
4646
matcher: boardsApi.endpoints.updateBoard.matchFulfilled,
4747
effect: async (action, { dispatch, getState }) => {
4848
const state = getState();
49-
const queryArgs = selectListBoardsQueryArgs(state);
50-
const queryResult = boardsApi.endpoints.listAllBoards.select(queryArgs)(state);
5149
const { shouldShowArchivedBoards } = state.gallery;
5250

53-
if (!queryResult.data) {
54-
return;
55-
}
56-
5751
const wasArchived = action.meta.arg.originalArgs.changes.archived === true;
5852

5953
if (wasArchived && !shouldShowArchivedBoards) {

0 commit comments

Comments
 (0)