@Override public void transitionInto(RunState state) { final String name = state.state().name().toLowerCase(); LOG.info("{}{} transition -> {} {}", prefix, state.workflowInstance(), name, stateInfo(state)); }
if (nextRunState.state().isTerminal()) { tx.deleteActiveState(event.workflowInstance()); } else {
.count()); for (State state : State.values()) { for (String triggerType : TriggerUtil.triggerTypesList()) { stats.registerActiveStatesMetric(state, triggerType, () -> activeStatesCache.get().values().stream() .filter(runState -> runState.state().equals(state)) .filter(runState -> runState.data().trigger() .map(TriggerUtil::triggerType) .filter(runState -> runState.state().equals(state)) .filter(runState -> !runState.data().trigger().isPresent()) .count());
final RunStateData runStateData = RunStateData.newBuilder() .workflowInstance(restoredState.workflowInstance()) .state(restoredState.state().name()) .stateData(restoredState.data()) .initialTimestamp(initialTime.get().toEpochMilli())
.set(PROPERTY_STATE, state.state().toString()) .set(PROPERTY_STATE_TIMESTAMP, state.timestamp()) .set(PROPERTY_STATE_TRIES, state.data().tries())
private void examineRunningWFISandAssociatedPods(Map<WorkflowInstance, RunState> activeStates, PodList podList) { final Map<WorkflowInstance, RunState> runningWorkflowInstances = Maps.filterValues(activeStates, runState -> runState.state().equals(RUNNING) && runState.data().executionId().isPresent()); final Set<WorkflowInstance> workflowInstancesForPods = podList.getItems().stream() .map(pod -> pod.getMetadata().getAnnotations()) .filter(Objects::nonNull) .map(annotations -> annotations.get(STYX_WORKFLOW_INSTANCE_ANNOTATION)) .filter(Objects::nonNull) .map(WorkflowInstance::parseKey) .collect(toSet()); // Emit errors for workflow instances that seem to be missing its pod runningWorkflowInstances.forEach((workflowInstance, runState) -> { // Is there a matching pod in the list? Bail. if (workflowInstancesForPods.contains(workflowInstance)) { return; } // The pod list might be stale so explicitly look for a pod using the execution ID. final String executionId = runState.data().executionId().get(); final Pod pod = client.pods().withName(executionId).get(); // We found a pod? Bail. if (pod != null) { return; } // No pod found. Emit an error guarded by the state counter we are basing the error conclusion on. stateManager.receiveIgnoreClosed( Event.runError(workflowInstance, "No pod associated with this instance"), runState.counter()); }); }
stats, DEPLOYING, SUBMITTED.name())); } catch (Exception e) { stats.recordPublishingError(DEPLOYING, SUBMITTED.name()); LOG.error("Failed to publish event for {} state", SUBMITTED.name(), e); stats, type, RUNNING.name())); } catch (Exception e) { stats.recordPublishingError(DEPLOYED, RUNNING.name()); LOG.error("Failed to publish event for {} state", RUNNING.name(), e);
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); }
private RunStateData getRunStateData(Backfill backfill, Map<WorkflowInstance, RunState> activeWorkflowInstances, Instant instant) { final WorkflowInstance wfi = WorkflowInstance .create(backfill.workflowId(), toParameter(backfill.schedule(), instant)); if (activeWorkflowInstances.containsKey(wfi)) { final RunState state = activeWorkflowInstances.get(wfi); return RunStateData.newBuilder() .workflowInstance(state.workflowInstance()) .state(state.state().name()) .stateData(state.data()) .latestTimestamp(state.timestamp()) .build(); } return ReplayEvents.getBackfillRunStateData(wfi, storage, backfill.id()) .orElse(RunStateData.create(wfi, UNKNOWN, StateData.zero())); } }
private static boolean hasTimedOut(Optional<Workflow> workflowOpt, RunState runState, Instant instant, Duration timeout) { if (runState.state().isTerminal()) { return false; } final Duration effectiveTimeout = runState.state() == RunState.State.RUNNING ? workflowOpt .flatMap(workflow -> workflow.configuration().runningTimeout()) .orElse(timeout) : timeout; final Duration sanitizedTimeout = effectiveTimeout.compareTo(timeout) < 0 ? effectiveTimeout : timeout; final Instant deadline = Instant .ofEpochMilli(runState.timestamp()) .plus(sanitizedTimeout); return !deadline.isAfter(instant); }
@Override public void registerActiveStatesMetric(RunState.State state, String triggerName, Gauge<Long> activeStatesCount) { registry.register(ACTIVE_STATES_PER_RUNSTATE_PER_TRIGGER.tagged( "state", state.name(), "trigger", triggerName), activeStatesCount); }
private RunStateData runStateToRunStateData(RunState state) { return RunStateData.newBuilder() .workflowInstance(state.workflowInstance()) .state(state.state().name()) .stateData(state.data()) .latestTimestamp(state.timestamp()) .build(); }
public static TimeoutConfig createFromConfig(Config ttlSubConfig) { final Duration defaultTtl = Duration.parse(ttlSubConfig.getString(DEFAULT_TTL_KEY)); final ImmutableMap.Builder<RunState.State, Duration> map = ImmutableMap.builder(); for (RunState.State state : RunState.State.values()) { final String key = state.name().toLowerCase(); if (ttlSubConfig.hasPath(key)) { final Duration ttl = Duration.parse(ttlSubConfig.getString(key)); map.put(state, ttl); } } return new TimeoutConfig(map.build(), defaultTtl); }
private static boolean isActiveState(RunStateData runStateData) { final String state = runStateData.state(); switch (state) { case UNKNOWN: return false; case WAITING: return false; default: return !RunState.State.valueOf(state).isTerminal(); } }