From 8f190169db49c617494f7723dae0a3b2b955958e Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Fri, 26 May 2023 15:53:08 +1000 Subject: [PATCH] feat(ui): improve session creation handling --- invokeai/frontend/web/public/locales/en.json | 1 + .../middleware/listenerMiddleware/index.ts | 10 +++ .../listeners/sessionCreated.ts | 45 ++++++++++++++ .../src/features/system/store/systemSlice.ts | 25 +++++++- .../web/src/services/events/middleware.ts | 11 +--- .../web/src/services/thunks/session.ts | 61 ++++++------------- 6 files changed, 99 insertions(+), 54 deletions(-) create mode 100644 invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/sessionCreated.ts diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index 94dff3934a..b96175c25d 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -546,6 +546,7 @@ "availableSchedulers": "Available Schedulers" }, "toast": { + "problemCreatingSession": "Problem Creating Session", "serverError": "Server Error", "disconnected": "Disconnected from Server", "connected": "Connected to Server", diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts index 8467b24c08..5c726c317f 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts @@ -44,6 +44,11 @@ import { addImageUrlsReceivedFulfilledListener, addImageUrlsReceivedRejectedListener, } from './listeners/imageUrlsReceived'; +import { + addSessionCreatedFulfilledListener, + addSessionCreatedPendingListener, + addSessionCreatedRejectedListener, +} from './listeners/sessionCreated'; export const listenerMiddleware = createListenerMiddleware(); @@ -106,3 +111,8 @@ addSocketConnectedListener(); addSocketDisconnectedListener(); addSocketSubscribedListener(); addSocketUnsubscribedListener(); + +// Sessions +addSessionCreatedPendingListener(); +addSessionCreatedFulfilledListener(); +addSessionCreatedRejectedListener(); diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/sessionCreated.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/sessionCreated.ts new file mode 100644 index 0000000000..e960510d0f --- /dev/null +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/sessionCreated.ts @@ -0,0 +1,45 @@ +import { log } from 'app/logging/useLogger'; +import { startAppListening } from '..'; +import { sessionCreated } from 'services/thunks/session'; +import { serializeError } from 'serialize-error'; + +const moduleLog = log.child({ namespace: 'session' }); + +export const addSessionCreatedPendingListener = () => { + startAppListening({ + actionCreator: sessionCreated.pending, + effect: (action, { getState, dispatch }) => { + // + }, + }); +}; + +export const addSessionCreatedFulfilledListener = () => { + startAppListening({ + actionCreator: sessionCreated.fulfilled, + effect: (action, { getState, dispatch }) => { + const session = action.payload; + moduleLog.info({ data: { session } }, `Session created (${session.id})`); + }, + }); +}; + +export const addSessionCreatedRejectedListener = () => { + startAppListening({ + actionCreator: sessionCreated.rejected, + effect: (action, { getState, dispatch }) => { + if (action.payload) { + const { arg, error } = action.payload; + moduleLog.error( + { + data: { + arg, + error: serializeError(error), + }, + }, + `Problem creating session` + ); + } + }, + }); +}; diff --git a/invokeai/frontend/web/src/features/system/store/systemSlice.ts b/invokeai/frontend/web/src/features/system/store/systemSlice.ts index 06fa0e47d8..8845e0b843 100644 --- a/invokeai/frontend/web/src/features/system/store/systemSlice.ts +++ b/invokeai/frontend/web/src/features/system/store/systemSlice.ts @@ -16,7 +16,11 @@ import { import { ProgressImage } from 'services/events/types'; import { makeToast } from '../../../app/components/Toaster'; -import { sessionCanceled, sessionInvoked } from 'services/thunks/session'; +import { + sessionCanceled, + sessionCreated, + sessionInvoked, +} from 'services/thunks/session'; import { receivedModels } from 'services/thunks/model'; import { parsedOpenAPISchema } from 'features/nodes/store/nodesSlice'; import { LogLevelName } from 'roarr'; @@ -353,7 +357,7 @@ export const systemSlice = createSlice({ }); /** - * Session Canceled + * Session Canceled - FULFILLED */ builder.addCase(sessionCanceled.fulfilled, (state, action) => { state.canceledSession = action.meta.arg.sessionId; @@ -370,6 +374,23 @@ export const systemSlice = createSlice({ ); }); + /** + * Session Created - REJECTED + */ + builder.addCase(sessionCreated.rejected, (state, action) => { + state.isProcessing = false; + state.isCancelable = false; + state.isCancelScheduled = false; + state.currentStep = 0; + state.totalSteps = 0; + state.statusTranslationKey = 'common.statusConnected'; + state.progressImage = null; + + state.toastQueue.push( + makeToast({ title: t('toast.problemCreatingSession'), status: 'error' }) + ); + }); + /** * Session Canceled */ diff --git a/invokeai/frontend/web/src/services/events/middleware.ts b/invokeai/frontend/web/src/services/events/middleware.ts index a78e0de97b..f1eb844f2c 100644 --- a/invokeai/frontend/web/src/services/events/middleware.ts +++ b/invokeai/frontend/web/src/services/events/middleware.ts @@ -8,11 +8,7 @@ import { import { socketSubscribed, socketUnsubscribed } from './actions'; import { AppThunkDispatch, RootState } from 'app/store/store'; import { getTimestamp } from 'common/util/getTimestamp'; -import { - sessionInvoked, - sessionCreated, - sessionWithoutGraphCreated, -} from 'services/thunks/session'; +import { sessionCreated } from 'services/thunks/session'; import { OpenAPI } from 'services/api'; import { setEventListeners } from 'services/events/util/setEventListeners'; import { log } from 'app/logging/useLogger'; @@ -66,10 +62,7 @@ export const socketMiddleware = () => { socket.connect(); } - if ( - sessionCreated.fulfilled.match(action) || - sessionWithoutGraphCreated.fulfilled.match(action) - ) { + if (sessionCreated.fulfilled.match(action)) { const sessionId = action.payload.id; const oldSessionId = getState().system.sessionId; diff --git a/invokeai/frontend/web/src/services/thunks/session.ts b/invokeai/frontend/web/src/services/thunks/session.ts index a1ee5a34ed..546789d5b7 100644 --- a/invokeai/frontend/web/src/services/thunks/session.ts +++ b/invokeai/frontend/web/src/services/thunks/session.ts @@ -1,7 +1,6 @@ import { createAppAsyncThunk } from 'app/store/storeUtils'; -import { SessionsService } from 'services/api'; +import { GraphExecutionState, SessionsService } from 'services/api'; import { log } from 'app/logging/useLogger'; -import { serializeError } from 'serialize-error'; const sessionLog = log.child({ namespace: 'session' }); @@ -11,51 +10,27 @@ type SessionCreatedArg = { >[0]['requestBody']; }; +type SessionCreatedThunkConfig = { + rejectValue: { arg: SessionCreatedArg; error: unknown }; +}; + /** * `SessionsService.createSession()` thunk */ -export const sessionCreated = createAppAsyncThunk( - 'api/sessionCreated', - async (arg: SessionCreatedArg, { rejectWithValue }) => { - try { - const response = await SessionsService.createSession({ - requestBody: arg.graph, - }); - sessionLog.info({ arg, response }, `Session created (${response.id})`); - return response; - } catch (err: any) { - sessionLog.error( - { - error: serializeError(err), - }, - 'Problem creating session' - ); - return rejectWithValue(err.message); - } +export const sessionCreated = createAppAsyncThunk< + GraphExecutionState, + SessionCreatedArg, + SessionCreatedThunkConfig +>('api/sessionCreated', async (arg: SessionCreatedArg, { rejectWithValue }) => { + try { + const response = await SessionsService.createSession({ + requestBody: arg.graph, + }); + return response; + } catch (error) { + return rejectWithValue({ arg, error }); } -); - -/** - * `SessionsService.createSession()` without graph thunk - */ -export const sessionWithoutGraphCreated = createAppAsyncThunk( - 'api/sessionWithoutGraphCreated', - async (_, { rejectWithValue }) => { - try { - const response = await SessionsService.createSession({}); - sessionLog.info({ response }, `Session created (${response.id})`); - return response; - } catch (err: any) { - sessionLog.error( - { - error: serializeError(err), - }, - 'Problem creating session' - ); - return rejectWithValue(err.message); - } - } -); +}); type NodeAddedArg = Parameters<(typeof SessionsService)['addNode']>[0];