| /** |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.aurora.scheduler.updater; |
| |
| import java.util.Optional; |
| |
| import static java.util.Objects.requireNonNull; |
| |
| /** |
| * Determines actions that must be taken to change the configuration of a running task. |
| * <p> |
| * A state evaluator is expected to be used multiple times over the course of changing an active |
| * task's configuration. This should be invoked every time the state of an instance changes to |
| * determine what action to take next. It's expected that it will eventually converge by |
| * {@link Result#SUCCEEDED succeeding}, or failing with {@link Result#FAILED_TERMINATED}. |
| * |
| * @param <T> Instance state type. |
| */ |
| interface StateEvaluator<T> { |
| |
| /** |
| * Evaluates the state differences between the desired state and the provided {@code actualState}. |
| * <p> |
| * This function should be idempotent, with the exception of an internal failure counter that |
| * increments when an updating task exits, or an active but not |
| * {@link org.apache.aurora.gen.ScheduleStatus#RUNNING RUNNING} task takes too long to start. |
| * <p> |
| * It is the responsibility of the caller to ensure that the {@code actualState} is the latest |
| * value. Note: the caller should avoid calling this when a terminal task is moving to another |
| * terminal state. It should also suppress deletion events for tasks that have been replaced by |
| * an active task. |
| * |
| * @param actualState The actual observed state of the task. |
| * @return the evaluation result, including the state of the instance update, and a necessary |
| * action to perform. |
| */ |
| Result evaluate(T actualState); |
| |
| Optional<Failure> NO_FAILURE = Optional.empty(); |
| |
| enum Result { |
| EVALUATE_ON_STATE_CHANGE(Optional.of(InstanceAction.AWAIT_STATE_CHANGE), NO_FAILURE), |
| REPLACE_TASK_AND_EVALUATE_ON_STATE_CHANGE(Optional.of(InstanceAction.ADD_TASK), NO_FAILURE), |
| KILL_TASK_AND_EVALUATE_ON_STATE_CHANGE(Optional.of(InstanceAction.KILL_TASK), NO_FAILURE), |
| KILL_TASK_WITH_RESERVATION_AND_EVALUATE_ON_STATE_CHANGE( |
| Optional.of(InstanceAction.KILL_TASK_AND_RESERVE), NO_FAILURE), |
| EVALUATE_AFTER_MIN_RUNNING_MS(Optional.of(InstanceAction.WATCH_TASK), NO_FAILURE), |
| SUCCEEDED(Optional.empty(), NO_FAILURE), |
| FAILED_TERMINATED(Optional.empty(), Optional.of(Failure.EXITED)); |
| |
| private final Optional<InstanceAction> action; |
| private final Optional<Failure> failure; |
| |
| Result(Optional<InstanceAction> action, Optional<Failure> failure) { |
| this.action = requireNonNull(action); |
| this.failure = requireNonNull(failure); |
| } |
| |
| public Optional<InstanceAction> getAction() { |
| return action; |
| } |
| |
| public Optional<Failure> getFailure() { |
| return failure; |
| } |
| } |
| |
| enum Failure { |
| EXITED("exited."); |
| |
| private final String reason; |
| |
| Failure(String reason) { |
| this.reason = reason; |
| } |
| |
| public String getReason() { |
| return reason; |
| } |
| } |
| } |