static StateDataBuilder newBuilder() { return new StateDataBuilder(); }
@Override public RunState retryAfter(WorkflowInstance workflowInstance, long delayMillis) { switch (state()) { case TERMINATED: case FAILED: case QUEUED: return state( QUEUED, data().builder() .retryDelayMillis(delayMillis) .executionId(empty()) .executionDescription(empty()) .resourceIds(empty()) .build()); default: throw illegalTransition("retryAfter"); } }
@Override public RunState dequeue(WorkflowInstance workflowInstance, Set<String> resourceIds) { switch (state()) { case QUEUED: return state( PREPARE, data().builder() .retryDelayMillis(empty()) .resourceIds(resourceIds) .build()); default: throw illegalTransition("dequeue"); } }
static RunState entityToRunState(Entity entity, WorkflowInstance instance) throws IOException { final long counter = entity.getLong(PROPERTY_COUNTER); final State state = State.valueOf(entity.getString(PROPERTY_STATE)); final long timestamp = entity.getLong(PROPERTY_STATE_TIMESTAMP); final StateData data = StateData.newBuilder() .tries((int) entity.getLong(PROPERTY_STATE_TRIES)) .consecutiveFailures((int) entity.getLong(PROPERTY_STATE_CONSECUTIVE_FAILURES)) .retryCost(entity.getDouble(PROPERTY_STATE_RETRY_COST)) .trigger(DatastoreStorage.<String>readOpt(entity, PROPERTY_STATE_TRIGGER_TYPE).map(type -> TriggerUtil.trigger(type, entity.getString(PROPERTY_STATE_TRIGGER_ID)))) .messages(OBJECT_MAPPER.<List<Message>>readValue(entity.getString(PROPERTY_STATE_MESSAGES), new TypeReference<List<Message>>() { })) .retryDelayMillis(readOpt(entity, PROPERTY_STATE_RETRY_DELAY_MILLIS)) .lastExit(DatastoreStorage.<Long>readOpt(entity, PROPERTY_STATE_LAST_EXIT).map(Long::intValue)) .executionId(readOpt(entity, PROPERTY_STATE_EXECUTION_ID)) .executionDescription(readOptJson(entity, PROPERTY_STATE_EXECUTION_DESCRIPTION, ExecutionDescription.class)) .resourceIds(readOptJson(entity, PROPERTY_STATE_RESOURCE_IDS, new TypeReference<Set<String>>() { })) .triggerParameters(readOptJson(entity, PROPERTY_STATE_TRIGGER_PARAMETERS, TriggerParameters.class)) .build(); return RunState.create(instance, state, data, Instant.ofEpochMilli(timestamp), counter); }
@Override public RunState runError(WorkflowInstance workflowInstance, String message) { switch (state()) { case QUEUED: case SUBMITTING: case SUBMITTED: case RUNNING: case PREPARE: final StateData newStateData = data().builder() .retryCost(data().retryCost() + FAILURE_COST) .lastExit(empty()) .consecutiveFailures(data().consecutiveFailures() + 1) .messages(Message.error(message)) .build(); return state(FAILED, newStateData); default: throw illegalTransition("runError"); } }
@Override public RunState triggerExecution(WorkflowInstance workflowInstance, Trigger trigger, TriggerParameters parameters) { switch (state()) { case NEW: return state( QUEUED, data().builder() .trigger(trigger) .triggerId(TriggerUtil.triggerId(trigger)) // for backwards compatibility .triggerParameters(parameters) .build()); default: throw illegalTransition("triggerExecution"); } }
@Deprecated @Override public RunState created(WorkflowInstance workflowInstance, String executionId, String dockerImage) { switch (state()) { case PREPARE: case QUEUED: return state( SUBMITTED, // for backwards compatibility data().builder() .executionId(executionId) .executionDescription(ExecutionDescription.forImage(dockerImage)) .tries(data().tries() + 1) .build()); default: throw illegalTransition("created"); } }
@Override public RunState submit(WorkflowInstance workflowInstance, ExecutionDescription executionDescription, String executionId) { switch (state()) { case QUEUED: // for backwards compatibility case PREPARE: return state( SUBMITTING, data().builder() .executionDescription(executionDescription) .executionId(executionId) .build()); default: throw illegalTransition("submit"); } }
@Deprecated @Override public RunState timeTrigger(WorkflowInstance workflowInstance) { switch (state()) { case NEW: return state( // for backwards compatibility SUBMITTED, data().builder() .trigger(Trigger.unknown("UNKNOWN")) .triggerId("UNKNOWN") // for backwards compatibility .build()); default: throw illegalTransition("timeTrigger"); } }
@Override public RunState submitted(WorkflowInstance workflowInstance, String executionId) { switch (state()) { case SUBMITTING: return state( SUBMITTED, data().builder() .tries(data().tries() + 1) // backwards compatibility .executionId(data().executionId().orElse(executionId)) .build()); default: throw illegalTransition("submitted"); } }
static StateData zero() { return newBuilder().build(); } }
@Override public RunState terminate(WorkflowInstance workflowInstance, Optional<Integer> exitCode) { switch (state()) { case RUNNING: final double cost = exitCost(exitCode); final int consecutiveFailures = consecutiveFailures(data(), exitCode); final MessageLevel level = messageLevel(exitCode); final StateData newStateData = data().builder() .retryCost(data().retryCost() + cost) .lastExit(exitCode) .consecutiveFailures(consecutiveFailures) .messages(Message.create(level, "Exit code: " + exitCode.map(String::valueOf).orElse("-"))) .build(); return state(TERMINATED, newStateData); default: throw illegalTransition("terminate"); } }