Skip to content
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

Collapsible validation time fix. #921

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 14 additions & 22 deletions frontend/src/components/experimentRuns/ExperimentRunValidation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Button, Collapse, List, Popconfirm, Space, Typography, Layout } from 'a
import React, { useCallback, useEffect, useState } from 'react'
import { useAppDispatch, useAppSelector } from '../../hooks'
import { useCurrentUser } from '../../hooks/useCurrentUser'
import { flushExperimentRunLanes, initExperimentRunLanes, setExpandedLanes, setRunLaneValidationStatus } from '../../modules/experimentRunLanes/actions'
import { flushExperimentRunLanes, initExperimentRunLanes, setExpandedLanes, setRunLaneValidationStatus, setRunLaneValidationTime } from '../../modules/experimentRunLanes/actions'
import { ExperimentRunLanes, LaneInfo, ValidationStatus } from '../../modules/experimentRunLanes/models'
import { selectExperimentRunLanesState, selectDatasetsByID } from '../../selectors'
import { addArchivedComment, get } from '../../modules/datasets/actions'
Expand Down Expand Up @@ -59,44 +59,36 @@ function ExperimentRunValidation({ experimentRunName }: ExperimentRunValidationP

}, [experimentRunName, experimentRunLanesState])

const updateLane = useCallback((lane: LaneInfo) => {
Promise.allSettled(lane.datasets.map((dataset) => dispatch(get(dataset.datasetID)))).finally(() => {
nafiz1001 marked this conversation as resolved.
Show resolved Hide resolved
dispatch(setRunLaneValidationTime(lane)).finally(() => {
setIsValidationInProgress(false)
})
})
}, [dispatch])

const setPassed = useCallback(
(lane: LaneInfo) => {
setIsValidationInProgress(true)
dispatch(setRunLaneValidationStatus(lane, ValidationStatus.PASSED))
.finally(() => {
lane.datasets.map((dataset) => {dispatch(get(dataset.datasetID))})
setIsValidationInProgress(false)
}
)
dispatch(setRunLaneValidationStatus(lane, ValidationStatus.PASSED)).finally(() => updateLane(lane))
},
[dispatch]
[dispatch, updateLane]
)

const setFailed = useCallback(
(lane: LaneInfo) => {
setIsValidationInProgress(true)
dispatch(setRunLaneValidationStatus(lane, ValidationStatus.FAILED))
.finally(async () => {
lane.datasets.map((dataset) => {dispatch(get(dataset.datasetID))})
setIsValidationInProgress(false)
}
)
dispatch(setRunLaneValidationStatus(lane, ValidationStatus.FAILED)).finally(() => updateLane(lane))
},
[dispatch]
[dispatch, updateLane]
)

const setAvailable = useCallback(
(lane: LaneInfo) => {
setIsValidationInProgress(true)
dispatch(setRunLaneValidationStatus(lane, ValidationStatus.AVAILABLE))
.finally(() => {
lane.datasets.map((dataset) => {dispatch(get(dataset.datasetID))})
setIsValidationInProgress(false)
}
)
dispatch(setRunLaneValidationStatus(lane, ValidationStatus.AVAILABLE)).finally(() => updateLane(lane))
},
[dispatch]
[dispatch, updateLane]
)

const setLaneExpansionState = useCallback((laneKeys: string | string[]) => {
Expand Down
26 changes: 25 additions & 1 deletion frontend/src/modules/experimentRunLanes/actions.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { ItemsByID } from "../../models/frontend_models"
import { AppDispatch } from "../../store"
import api from "../../utils/api"
import { ValidationStatus } from "./models"
import { LaneInfo, LaneNumber } from "./models"
import { FLUSH_EXPERIMENT_LANES, SET_EXPANDED_LANES, SET_EXPERIMENT_LANES, SET_LANE_VALIDATION_STATUS, SET_READS_PER_SAMPLE } from "./reducers"
import { Dataset } from '../../models/frontend_models'
import { FLUSH_EXPERIMENT_LANES, SET_EXPANDED_LANES, SET_EXPERIMENT_LANES, SET_LANE_VALIDATION_STATUS, SET_LANE_VALIDATION_TIME, SET_READS_PER_SAMPLE } from "./reducers"
import { fetchReadsPerSample, loadExperimentRunLanes } from "./services"


Expand Down Expand Up @@ -44,6 +46,28 @@ export function setRunLaneValidationStatus(lane: LaneInfo, status: ValidationSta
}
}

export function setRunLaneValidationTime(lane: LaneInfo) {
return async (dispatch, getState) => {
const validationTime = lane.datasets.reduce<string | undefined>((latest, dataset) => {
const currentDatasetTime = getState().datasets.itemsByID[dataset.datasetID].latest_validation_update
nafiz1001 marked this conversation as resolved.
Show resolved Hide resolved
if (currentDatasetTime) {
if (!latest || currentDatasetTime > latest) {
return currentDatasetTime
}
}
return latest
}, undefined)
// NOTE: Loading experiment runs is expensive so, rather than reloading
// everything from the server, we just update the lane's validation time in the redux store.
dispatch({
type: SET_LANE_VALIDATION_TIME,
experimentRunName: lane.runName,
laneNumber: lane.laneNumber,
validationTime: validationTime
})
}
}

export function flushExperimentRunLanes(experimentRunName: string) {
return {
type: FLUSH_EXPERIMENT_LANES,
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/modules/experimentRunLanes/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export interface LaneInfo {
runName: string // Name of the run, for both freezeman and external runs
laneNumber: LaneNumber // The number of the lane
validationStatus: ValidationStatus // The validation status for the lane
validationTime?: string // The time at which the lane was last validated
validationTime?: string // The time at which the lane was last validated
datasets: DatasetInfo[] // List of datasets associated with lane (may be more than one)
readsPerSample?: ReadsPerSample // List of reads counts per sample (loaded on demand)
}
Expand Down
13 changes: 13 additions & 0 deletions frontend/src/modules/experimentRunLanes/reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import produce, { Draft } from "immer"
export const SET_EXPERIMENT_LANES = 'EXPERIMENT_RUN_LANES:SET_EXPERIMENT_LANES'
export const SET_READS_PER_SAMPLE = 'EXPERIMENT_RUN_LANES:SET_READS_PER_SAMPLE'
export const SET_LANE_VALIDATION_STATUS = 'EXPERIMENT_RUN_LANES:SET_LANE_VALIDATION_STATUS'
export const SET_LANE_VALIDATION_TIME = 'EXPERIMENT_RUN_LANES:SET_LANE_VALIDATION_TIME'
export const FLUSH_EXPERIMENT_LANES = 'EXPERIMENT_RUN_LANES:FLUSH_EXPERIMENT_LANES'
export const SET_EXPANDED_LANES = 'EXPERIMENT_RUN_LANES:SET_EXPANDED_LANES'

Expand Down Expand Up @@ -56,6 +57,18 @@ function reducers(state: Draft<ExperimentRunLanesState>, action: AnyAction): Exp
break
}

case SET_LANE_VALIDATION_TIME: {
const { experimentRunName, laneNumber, validationTime} = action
const experimentRunLanes = state.runs[experimentRunName] as ExperimentRunLanes
if (experimentRunLanes) {
const lane = experimentRunLanes.lanes.find(x => x.laneNumber === laneNumber)
if (lane) {
lane.validationTime = validationTime
}
}
break
}

Copy link
Contributor

@nafiz1001 nafiz1001 Feb 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My condolence.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thankfully it's using immer.

case FLUSH_EXPERIMENT_LANES: {
const { experimentRunName } = action
delete state.runs[experimentRunName]
Expand Down