From e24137bff5e66355cb00357465a8ba5da307fa43 Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Sat, 2 Mar 2024 22:34:14 +0900 Subject: [PATCH 1/5] Use boolean state for api call --- optuna_dashboard/ts/action.ts | 5 +++++ optuna_dashboard/ts/components/StudyDetail.tsx | 10 ++++++++-- optuna_dashboard/ts/state.ts | 5 +++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/optuna_dashboard/ts/action.ts b/optuna_dashboard/ts/action.ts index a0037f46..c4ad3cd9 100644 --- a/optuna_dashboard/ts/action.ts +++ b/optuna_dashboard/ts/action.ts @@ -27,6 +27,7 @@ import { isFileUploading, artifactIsAvailable, plotlypyIsAvailableState, + reloadingState, reloadIntervalState, trialsUpdatingState, studySummariesLoadingState, @@ -40,6 +41,7 @@ export const actionCreator = () => { useRecoilState(studySummariesState) const [studyDetails, setStudyDetails] = useRecoilState(studyDetailsState) + const setReloading = useSetRecoilState(reloadingState) const setReloadInterval = useSetRecoilState(reloadIntervalState) const setUploading = useSetRecoilState(isFileUploading) const setTrialsUpdating = useSetRecoilState(trialsUpdatingState) @@ -231,6 +233,7 @@ export const actionCreator = () => { } const updateStudyDetail = (studyId: number) => { + setReloading(true) let nLocalFixedTrials = 0 if (studyId in studyDetails) { const currentTrials = studyDetails[studyId].trials @@ -242,6 +245,7 @@ export const actionCreator = () => { } getStudyDetailAPI(studyId, nLocalFixedTrials) .then((study) => { + setReloading(false) const currentFixedTrials = studyId in studyDetails ? studyDetails[studyId].trials.slice(0, nLocalFixedTrials) @@ -250,6 +254,7 @@ export const actionCreator = () => { setStudyDetailState(studyId, study) }) .catch((err) => { + setReloading(false) const reason = err.response?.data.reason if (reason !== undefined) { enqueueSnackbar(`Failed to fetch study (reason=${reason})`, { diff --git a/optuna_dashboard/ts/components/StudyDetail.tsx b/optuna_dashboard/ts/components/StudyDetail.tsx index 065b90f5..963f7826 100644 --- a/optuna_dashboard/ts/components/StudyDetail.tsx +++ b/optuna_dashboard/ts/components/StudyDetail.tsx @@ -16,6 +16,7 @@ import HomeIcon from "@mui/icons-material/Home" import { StudyNote } from "./Note" import { actionCreator } from "../action" import { + reloadingState, reloadIntervalState, useStudyDetailValue, useStudyIsPreferential, @@ -53,6 +54,7 @@ export const StudyDetail: FC<{ const action = actionCreator() const studyId = useURLVars() const studyDetail = useStudyDetailValue(studyId) + const isLoading = useRecoilValue(reloadingState) const reloadInterval = useRecoilValue(reloadIntervalState) const studyName = useStudyName(studyId) const isPreferential = useStudyIsPreferential(studyId) @@ -61,7 +63,9 @@ export const StudyDetail: FC<{ studyName !== null ? `${studyName} (id=${studyId})` : `Study #${studyId}` useEffect(() => { - action.updateStudyDetail(studyId) + if (!isLoading) { + action.updateStudyDetail(studyId) + } action.updateAPIMeta() }, []) @@ -86,7 +90,9 @@ export const StudyDetail: FC<{ } const intervalId = setInterval(function () { - action.updateStudyDetail(studyId) + if (!isLoading) { + action.updateStudyDetail(studyId) + } }, interval) return () => clearInterval(intervalId) }, [reloadInterval, studyDetail, page]) diff --git a/optuna_dashboard/ts/state.ts b/optuna_dashboard/ts/state.ts index 5828985f..bac5d641 100644 --- a/optuna_dashboard/ts/state.ts +++ b/optuna_dashboard/ts/state.ts @@ -21,6 +21,11 @@ export const trialsUpdatingState = atom<{ default: {}, }) +export const reloadingState = atom({ + key: "reloadng", + default: false, +}) + // TODO(c-bata): Consider representing the state as boolean. export const reloadIntervalState = atom({ key: "reloadInterval", From 3745b23eb986d4a81117b0887895434935e0374b Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Mon, 4 Mar 2024 17:50:02 +0900 Subject: [PATCH 2/5] Rename state --- optuna_dashboard/ts/action.ts | 12 +++++++----- optuna_dashboard/ts/components/StudyDetail.tsx | 4 ++-- optuna_dashboard/ts/state.ts | 10 +++++----- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/optuna_dashboard/ts/action.ts b/optuna_dashboard/ts/action.ts index c4ad3cd9..1a59d8fe 100644 --- a/optuna_dashboard/ts/action.ts +++ b/optuna_dashboard/ts/action.ts @@ -27,7 +27,7 @@ import { isFileUploading, artifactIsAvailable, plotlypyIsAvailableState, - reloadingState, + studyDetailLoadingState, reloadIntervalState, trialsUpdatingState, studySummariesLoadingState, @@ -41,7 +41,6 @@ export const actionCreator = () => { useRecoilState(studySummariesState) const [studyDetails, setStudyDetails] = useRecoilState(studyDetailsState) - const setReloading = useSetRecoilState(reloadingState) const setReloadInterval = useSetRecoilState(reloadIntervalState) const setUploading = useSetRecoilState(isFileUploading) const setTrialsUpdating = useSetRecoilState(trialsUpdatingState) @@ -52,6 +51,9 @@ export const actionCreator = () => { const setStudySummariesLoading = useSetRecoilState( studySummariesLoadingState ) + const setStudyDetailLoading = useSetRecoilState( + studyDetailLoadingState + ) const setStudyDetailState = (studyId: number, study: StudyDetail) => { setStudyDetails((prevVal) => { @@ -233,7 +235,7 @@ export const actionCreator = () => { } const updateStudyDetail = (studyId: number) => { - setReloading(true) + setStudyDetailLoading(true) let nLocalFixedTrials = 0 if (studyId in studyDetails) { const currentTrials = studyDetails[studyId].trials @@ -245,7 +247,7 @@ export const actionCreator = () => { } getStudyDetailAPI(studyId, nLocalFixedTrials) .then((study) => { - setReloading(false) + setStudyDetailLoading(false) const currentFixedTrials = studyId in studyDetails ? studyDetails[studyId].trials.slice(0, nLocalFixedTrials) @@ -254,7 +256,7 @@ export const actionCreator = () => { setStudyDetailState(studyId, study) }) .catch((err) => { - setReloading(false) + setStudyDetailLoading(false) const reason = err.response?.data.reason if (reason !== undefined) { enqueueSnackbar(`Failed to fetch study (reason=${reason})`, { diff --git a/optuna_dashboard/ts/components/StudyDetail.tsx b/optuna_dashboard/ts/components/StudyDetail.tsx index 963f7826..ff9ac356 100644 --- a/optuna_dashboard/ts/components/StudyDetail.tsx +++ b/optuna_dashboard/ts/components/StudyDetail.tsx @@ -16,7 +16,7 @@ import HomeIcon from "@mui/icons-material/Home" import { StudyNote } from "./Note" import { actionCreator } from "../action" import { - reloadingState, + studyDetailLoadingState, reloadIntervalState, useStudyDetailValue, useStudyIsPreferential, @@ -54,7 +54,7 @@ export const StudyDetail: FC<{ const action = actionCreator() const studyId = useURLVars() const studyDetail = useStudyDetailValue(studyId) - const isLoading = useRecoilValue(reloadingState) + const isLoading = useRecoilValue(studyDetailLoadingState) const reloadInterval = useRecoilValue(reloadIntervalState) const studyName = useStudyName(studyId) const isPreferential = useStudyIsPreferential(studyId) diff --git a/optuna_dashboard/ts/state.ts b/optuna_dashboard/ts/state.ts index bac5d641..19659aa4 100644 --- a/optuna_dashboard/ts/state.ts +++ b/optuna_dashboard/ts/state.ts @@ -21,11 +21,6 @@ export const trialsUpdatingState = atom<{ default: {}, }) -export const reloadingState = atom({ - key: "reloadng", - default: false, -}) - // TODO(c-bata): Consider representing the state as boolean. export const reloadIntervalState = atom({ key: "reloadInterval", @@ -70,6 +65,11 @@ export const studySummariesLoadingState = atom({ default: false, }) +export const studyDetailLoadingState = atom({ + key: "studyDetailLoading", + default: false, +}) + export const useStudyDetailValue = (studyId: number): StudyDetail | null => { const studyDetails = useRecoilValue(studyDetailsState) return studyDetails[studyId] || null From b3a63b2d75c2a6d97aec31960d8111392b564780 Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Mon, 4 Mar 2024 17:58:00 +0900 Subject: [PATCH 3/5] Create state for each study --- optuna_dashboard/ts/action.ts | 12 ++++++------ optuna_dashboard/ts/components/StudyDetail.tsx | 8 +++++--- optuna_dashboard/ts/state.ts | 4 ++-- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/optuna_dashboard/ts/action.ts b/optuna_dashboard/ts/action.ts index 1a59d8fe..04c3532b 100644 --- a/optuna_dashboard/ts/action.ts +++ b/optuna_dashboard/ts/action.ts @@ -51,9 +51,9 @@ export const actionCreator = () => { const setStudySummariesLoading = useSetRecoilState( studySummariesLoadingState ) - const setStudyDetailLoading = useSetRecoilState( - studyDetailLoadingState - ) + const [studyDetailLoading, setStudyDetailLoading] = useRecoilState< + Record + >(studyDetailLoadingState) const setStudyDetailState = (studyId: number, study: StudyDetail) => { setStudyDetails((prevVal) => { @@ -235,7 +235,7 @@ export const actionCreator = () => { } const updateStudyDetail = (studyId: number) => { - setStudyDetailLoading(true) + setStudyDetailLoading({ ...studyDetailLoading, [studyId]: true }) let nLocalFixedTrials = 0 if (studyId in studyDetails) { const currentTrials = studyDetails[studyId].trials @@ -247,7 +247,7 @@ export const actionCreator = () => { } getStudyDetailAPI(studyId, nLocalFixedTrials) .then((study) => { - setStudyDetailLoading(false) + setStudyDetailLoading({ ...studyDetailLoading, [studyId]: false }) const currentFixedTrials = studyId in studyDetails ? studyDetails[studyId].trials.slice(0, nLocalFixedTrials) @@ -256,7 +256,7 @@ export const actionCreator = () => { setStudyDetailState(studyId, study) }) .catch((err) => { - setStudyDetailLoading(false) + setStudyDetailLoading({ ...studyDetailLoading, [studyId]: false }) const reason = err.response?.data.reason if (reason !== undefined) { enqueueSnackbar(`Failed to fetch study (reason=${reason})`, { diff --git a/optuna_dashboard/ts/components/StudyDetail.tsx b/optuna_dashboard/ts/components/StudyDetail.tsx index ff9ac356..eaa17bb0 100644 --- a/optuna_dashboard/ts/components/StudyDetail.tsx +++ b/optuna_dashboard/ts/components/StudyDetail.tsx @@ -54,7 +54,9 @@ export const StudyDetail: FC<{ const action = actionCreator() const studyId = useURLVars() const studyDetail = useStudyDetailValue(studyId) - const isLoading = useRecoilValue(studyDetailLoadingState) + const isLoading = useRecoilValue>( + studyDetailLoadingState + ) const reloadInterval = useRecoilValue(reloadIntervalState) const studyName = useStudyName(studyId) const isPreferential = useStudyIsPreferential(studyId) @@ -63,7 +65,7 @@ export const StudyDetail: FC<{ studyName !== null ? `${studyName} (id=${studyId})` : `Study #${studyId}` useEffect(() => { - if (!isLoading) { + if (!isLoading[studyId]) { action.updateStudyDetail(studyId) } action.updateAPIMeta() @@ -90,7 +92,7 @@ export const StudyDetail: FC<{ } const intervalId = setInterval(function () { - if (!isLoading) { + if (!isLoading[studyId]) { action.updateStudyDetail(studyId) } }, interval) diff --git a/optuna_dashboard/ts/state.ts b/optuna_dashboard/ts/state.ts index 19659aa4..0811c51a 100644 --- a/optuna_dashboard/ts/state.ts +++ b/optuna_dashboard/ts/state.ts @@ -65,9 +65,9 @@ export const studySummariesLoadingState = atom({ default: false, }) -export const studyDetailLoadingState = atom({ +export const studyDetailLoadingState = atom>({ key: "studyDetailLoading", - default: false, + default: {}, }) export const useStudyDetailValue = (studyId: number): StudyDetail | null => { From f667ce0c87825da7d858b81810e790c58ce18941 Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Sun, 10 Mar 2024 16:36:20 +0900 Subject: [PATCH 4/5] Move isLoading into action --- optuna_dashboard/ts/action.ts | 3 +++ optuna_dashboard/ts/components/StudyDetail.tsx | 11 ++--------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/optuna_dashboard/ts/action.ts b/optuna_dashboard/ts/action.ts index 04c3532b..ff66b8e9 100644 --- a/optuna_dashboard/ts/action.ts +++ b/optuna_dashboard/ts/action.ts @@ -235,6 +235,9 @@ export const actionCreator = () => { } const updateStudyDetail = (studyId: number) => { + if (studyDetailLoading[studyId]) { + return + } setStudyDetailLoading({ ...studyDetailLoading, [studyId]: true }) let nLocalFixedTrials = 0 if (studyId in studyDetails) { diff --git a/optuna_dashboard/ts/components/StudyDetail.tsx b/optuna_dashboard/ts/components/StudyDetail.tsx index eaa17bb0..7a29c63e 100644 --- a/optuna_dashboard/ts/components/StudyDetail.tsx +++ b/optuna_dashboard/ts/components/StudyDetail.tsx @@ -54,9 +54,6 @@ export const StudyDetail: FC<{ const action = actionCreator() const studyId = useURLVars() const studyDetail = useStudyDetailValue(studyId) - const isLoading = useRecoilValue>( - studyDetailLoadingState - ) const reloadInterval = useRecoilValue(reloadIntervalState) const studyName = useStudyName(studyId) const isPreferential = useStudyIsPreferential(studyId) @@ -65,9 +62,7 @@ export const StudyDetail: FC<{ studyName !== null ? `${studyName} (id=${studyId})` : `Study #${studyId}` useEffect(() => { - if (!isLoading[studyId]) { - action.updateStudyDetail(studyId) - } + action.updateStudyDetail(studyId) action.updateAPIMeta() }, []) @@ -92,9 +87,7 @@ export const StudyDetail: FC<{ } const intervalId = setInterval(function () { - if (!isLoading[studyId]) { - action.updateStudyDetail(studyId) - } + action.updateStudyDetail(studyId) }, interval) return () => clearInterval(intervalId) }, [reloadInterval, studyDetail, page]) From d870a238c9bf7f9e4b21ec6c48edb9791d032a88 Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Sun, 17 Mar 2024 17:33:14 +0900 Subject: [PATCH 5/5] Fix ling --- optuna_dashboard/ts/components/StudyDetail.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/optuna_dashboard/ts/components/StudyDetail.tsx b/optuna_dashboard/ts/components/StudyDetail.tsx index 7a29c63e..065b90f5 100644 --- a/optuna_dashboard/ts/components/StudyDetail.tsx +++ b/optuna_dashboard/ts/components/StudyDetail.tsx @@ -16,7 +16,6 @@ import HomeIcon from "@mui/icons-material/Home" import { StudyNote } from "./Note" import { actionCreator } from "../action" import { - studyDetailLoadingState, reloadIntervalState, useStudyDetailValue, useStudyIsPreferential,