001/*-
002 * #%L
003 * HAPI FHIR JPA Server - Batch2 Task Processor
004 * %%
005 * Copyright (C) 2014 - 2024 Smile CDR, Inc.
006 * %%
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 *
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 * #L%
019 */
020package ca.uhn.fhir.batch2.model;
021
022import java.util.EnumMap;
023import java.util.EnumSet;
024import java.util.Set;
025
026/**
027 * States for the {@link WorkChunk} state machine.
028 * The initial state is QUEUED.
029 * The terminal states are FAILED, COMPLETED.
030 *
031 * @see hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa_batch/batch2_states.md
032 */
033public enum WorkChunkStatusEnum {
034        /**
035         * The initial state all workchunks start in for non-gated jobs.
036         */
037        READY,
038        /**
039         * The initial state all workchunks start in for gated jobs.
040         */
041        GATE_WAITING,
042        /**
043         * Workchunk is ready for reduction pass.
044         * It will not be QUEUED, but consumed inline by reduction pass.
045         */
046        REDUCTION_READY,
047        /**
048         * The state of workchunks that have been sent to the queue;
049         * or of workchunks that are about to be processed in a final
050         * reduction step (these workchunks are never queued)
051         */
052        QUEUED,
053        /**
054         * The state of workchunks that are doing work.
055         */
056        IN_PROGRESS,
057        /**
058         * A workchunk status for workchunks that are doing long-polling work
059         * that will not complete in a reasonably short amount of time
060         */
061        POLL_WAITING,
062        /**
063         * A transient state on retry when a chunk throws an error, but hasn't FAILED yet. Will move back to IN_PROGRESS on retry.
064         */
065        ERRORED,
066        /**
067         * Chunk has failed with a non-retriable error, or has run out of retry attempts.
068         */
069        FAILED,
070        /**
071         * The state of workchunks that have finished their job's step.
072         */
073        COMPLETED;
074
075        private static final EnumMap<WorkChunkStatusEnum, Set<WorkChunkStatusEnum>> ourPriorStates;
076
077        static {
078                ourPriorStates = new EnumMap<>(WorkChunkStatusEnum.class);
079                for (WorkChunkStatusEnum nextEnum : WorkChunkStatusEnum.values()) {
080                        ourPriorStates.put(nextEnum, EnumSet.noneOf(WorkChunkStatusEnum.class));
081                }
082                for (WorkChunkStatusEnum nextPriorEnum : WorkChunkStatusEnum.values()) {
083                        for (WorkChunkStatusEnum nextEnum : nextPriorEnum.getNextStates()) {
084                                ourPriorStates.get(nextEnum).add(nextPriorEnum);
085                        }
086                }
087        }
088
089        public boolean isIncomplete() {
090                return (this != WorkChunkStatusEnum.COMPLETED);
091        }
092
093        public boolean isAReadyState() {
094                return this == WorkChunkStatusEnum.READY || this == WorkChunkStatusEnum.REDUCTION_READY;
095        }
096
097        public Set<WorkChunkStatusEnum> getNextStates() {
098                switch (this) {
099                        case GATE_WAITING:
100                                return EnumSet.of(READY);
101                        case READY:
102                                return EnumSet.of(QUEUED);
103                        case REDUCTION_READY:
104                                // currently no support for POLL_WAITING reduction steps
105                                return EnumSet.of(COMPLETED, FAILED);
106                        case QUEUED:
107                                return EnumSet.of(IN_PROGRESS);
108                        case IN_PROGRESS:
109                                return EnumSet.of(IN_PROGRESS, ERRORED, FAILED, COMPLETED, POLL_WAITING);
110                        case POLL_WAITING:
111                                return EnumSet.of(POLL_WAITING, READY);
112                        case ERRORED:
113                                return EnumSet.of(IN_PROGRESS, FAILED, COMPLETED);
114                                // terminal states
115                        case FAILED:
116                        case COMPLETED:
117                        default:
118                                return EnumSet.noneOf(WorkChunkStatusEnum.class);
119                }
120        }
121
122        public Set<WorkChunkStatusEnum> getPriorStates() {
123                return ourPriorStates.get(this);
124        }
125}