Merge branch 'master' into 14491-graph-field-is-too-big-when-no-workflows-were-chosen
[arvados.git] / src / store / processes / process.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { ContainerRequestResource, ContainerRequestState } from '../../models/container-request';
6 import { ContainerResource, ContainerState } from '../../models/container';
7 import { ResourcesState, getResource } from '~/store/resources/resources';
8 import { filterResources } from '../resources/resources';
9 import { ResourceKind, Resource, extractUuidKind } from '~/models/resource';
10 import { getTimeDiff } from '~/common/formatters';
11 import { ArvadosTheme } from '~/common/custom-theme';
12
13 export interface Process {
14     containerRequest: ContainerRequestResource;
15     container?: ContainerResource;
16 }
17
18 export enum ProcessStatus {
19     CANCELLED = 'Cancelled',
20     COMPLETED = 'Completed',
21     DRAFT = 'Draft',
22     FAILED = 'Failed',
23     LOCKED = 'Locked',
24     QUEUED = 'Queued',
25     RUNNING = 'Running',
26     UNKNOWN = 'Unknown',
27 }
28
29 export const getProcess = (uuid: string) => (resources: ResourcesState): Process | undefined => {
30     if (extractUuidKind(uuid) === ResourceKind.CONTAINER_REQUEST) {
31         const containerRequest = getResource<ContainerRequestResource>(uuid)(resources);
32         if (containerRequest) {
33             if (containerRequest.containerUuid) {
34                 const container = getResource<ContainerResource>(containerRequest.containerUuid)(resources);
35                 if (container) {
36                     return { containerRequest, container };
37                 }
38             }
39             return { containerRequest };
40         }
41     }
42     return;
43 };
44
45 export const getSubprocesses = (uuid: string) => (resources: ResourcesState) => {
46     const process = getProcess(uuid)(resources);
47     if (process && process.container) {
48         const containerRequests = filterResources(isSubprocess(process.container.uuid))(resources) as ContainerRequestResource[];
49         return containerRequests.reduce((subprocesses, { uuid }) => {
50             const process = getProcess(uuid)(resources);
51             return process
52                 ? [...subprocesses, process]
53                 : subprocesses;
54         }, []);
55     }
56     return [];
57 };
58
59 export const getProcessRuntime = ({ container }: Process) =>
60     container
61         ? getTimeDiff(container.finishedAt || '', container.startedAt || '')
62         : 0;
63
64 export const getProcessStatusColor = (status: string, { customs, palette }: ArvadosTheme) => {
65     switch (status) {
66         case ProcessStatus.RUNNING:
67             return customs.colors.blue500;
68         case ProcessStatus.COMPLETED:
69             return customs.colors.green700;
70         case ProcessStatus.CANCELLED:
71         case ProcessStatus.FAILED:
72             return customs.colors.red900;
73         default:
74             return palette.grey["500"];
75     }
76 };
77
78 export const getProcessStatus = ({ containerRequest, container }: Process): ProcessStatus => {
79     switch (true) {
80         case containerRequest.state === ContainerRequestState.UNCOMMITTED:
81             return ProcessStatus.DRAFT;
82
83         case containerRequest.priority === 0:
84         case container && container.state === ContainerState.CANCELLED:
85             return ProcessStatus.CANCELLED;
86
87         case container && container.state === ContainerState.QUEUED:
88             return ProcessStatus.QUEUED;
89
90         case container && container.state === ContainerState.LOCKED:
91             return ProcessStatus.LOCKED;
92
93         case container && container.state === ContainerState.RUNNING:
94             return ProcessStatus.RUNNING;
95
96         case container && container.state === ContainerState.COMPLETE && container.exitCode === 0:
97             return ProcessStatus.COMPLETED;
98
99         case container && container.state === ContainerState.COMPLETE && container.exitCode !== 0:
100             return ProcessStatus.FAILED;
101
102         default:
103             return ProcessStatus.UNKNOWN;
104     }
105 };
106
107 const isSubprocess = (containerUuid: string) => (resource: Resource) =>
108     resource.kind === ResourceKind.CONTAINER_REQUEST
109     && (resource as ContainerRequestResource).requestingContainerUuid === containerUuid;