X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/0f5b0542513b572959e39400bae42e69aeb1a7b6..2037dc353ddfc0ae182189f69159ef00e637fba9:/services/workbench2/src/store/subprocess-panel/subprocess-panel-actions.ts diff --git a/services/workbench2/src/store/subprocess-panel/subprocess-panel-actions.ts b/services/workbench2/src/store/subprocess-panel/subprocess-panel-actions.ts index b440776ce0..a67dd1f436 100644 --- a/services/workbench2/src/store/subprocess-panel/subprocess-panel-actions.ts +++ b/services/workbench2/src/store/subprocess-panel/subprocess-panel-actions.ts @@ -6,6 +6,9 @@ import { Dispatch } from 'redux'; import { RootState } from 'store/store'; import { ServiceRepository } from 'services/services'; import { bindDataExplorerActions } from 'store/data-explorer/data-explorer-action'; +import { FilterBuilder } from 'services/api/filter-builder'; +import { ProgressBarData } from 'components/subprocess-progress-bar/subprocess-progress-bar'; +import { ProcessStatusFilter, buildProcessStatusFilters } from 'store/resource-type-filters/resource-type-filters'; export const SUBPROCESS_PANEL_ID = "subprocessPanel"; export const SUBPROCESS_ATTRIBUTES_DIALOG = 'subprocessAttributesDialog'; export const subprocessPanelActions = bindDataExplorerActions(SUBPROCESS_PANEL_ID); @@ -14,3 +17,81 @@ export const loadSubprocessPanel = () => (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { dispatch(subprocessPanelActions.REQUEST_ITEMS()); }; + +/** + * Holds a ProgressBarData status type and process count result + */ +type ProcessStatusBarCount = { + status: keyof ProgressBarData; + count: number; +}; + +/** + * Associates each of the limited progress bar segment types with an array of + * ProcessStatusFilterTypes to be combined when displayed + */ +type ProcessStatusMap = Record; + +const statusMap: ProcessStatusMap = { + [ProcessStatusFilter.COMPLETED]: [ProcessStatusFilter.COMPLETED], + [ProcessStatusFilter.RUNNING]: [ProcessStatusFilter.RUNNING], + [ProcessStatusFilter.FAILED]: [ProcessStatusFilter.FAILED, ProcessStatusFilter.CANCELLED], + [ProcessStatusFilter.QUEUED]: [ProcessStatusFilter.QUEUED, ProcessStatusFilter.ONHOLD], +}; + +/** + * Utility type to hold a pair of associated progress bar status and process status + */ +type ProgressBarStatusPair = { + barStatus: keyof ProcessStatusMap; + processStatus: ProcessStatusFilter; +}; + +export const fetchSubprocessProgress = (requestingContainerUuid: string) => + async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository): Promise => { + + const requestContainerStatusCount = async (fb: FilterBuilder) => { + return await services.containerRequestService.list({ + limit: 0, + offset: 0, + filters: fb.getFilters(), + }); + } + + if (requestingContainerUuid) { + try { + const baseFilter = new FilterBuilder().addEqual('requesting_container_uuid', requestingContainerUuid).getFilters(); + + // Create return object + let result: ProgressBarData = { + [ProcessStatusFilter.COMPLETED]: 0, + [ProcessStatusFilter.RUNNING]: 0, + [ProcessStatusFilter.FAILED]: 0, + [ProcessStatusFilter.QUEUED]: 0, + } + + // Create array of promises that returns the status associated with the item count + // Helps to make the requests simultaneously while preserving the association with the status key as a typed key + const promises = (Object.keys(statusMap) as Array) + // Split statusMap into pairs of progress bar status and process status + .reduce((acc, curr) => [...acc, ...statusMap[curr].map(processStatus => ({barStatus: curr, processStatus}))], [] as ProgressBarStatusPair[]) + .map(async (statusPair: ProgressBarStatusPair): Promise => { + // For each status pair, request count and return bar status and count + const { barStatus, processStatus } = statusPair; + const filter = buildProcessStatusFilters(new FilterBuilder(baseFilter), processStatus); + const count = (await requestContainerStatusCount(filter)).itemsAvailable; + return {status: barStatus, count}; + }); + + // Simultaneously requests each status count and apply them to the return object + (await Promise.all(promises)).forEach((singleResult) => { + result[singleResult.status] += singleResult.count; + }); + return result; + } catch (e) { + return undefined; + } + } else { + return undefined; + } + };