@Override public void addStage(@Nonnull Stage stage) { if (stage.getSyntheticStageOwner() == null || stage.getParentStageId() == null) { throw new IllegalArgumentException("Only synthetic stages can be inserted ad-hoc"); } storeStageInternal(getRedisDelegate(stage), stage, true); }
/** * Implement this method to define any stages that should run after any tasks in * this stage as part of a composed workflow. * <p> * This default implementation is for backward compatibility with the legacy * {@link #aroundStages} and {@link #parallelStages} methods. */ default void afterStages( @Nonnull Stage parent, @Nonnull StageGraphBuilder graph ) { List<Stage> stages = aroundStages(parent) .stream() .filter((it) -> it.getSyntheticStageOwner() == STAGE_AFTER) .collect(toList()); if (!stages.isEmpty()) { graph.add(stages.get(0)); } for (int i = 1; i < stages.size(); i++) { graph.connect(stages.get(i - 1), stages.get(i)); } parallelStages(parent) .stream() .filter((it) -> it.getSyntheticStageOwner() == STAGE_AFTER) .forEach(graph::add); }
/** * Implement this method to define any stages that should run before any tasks in * this stage as part of a composed workflow. * <p> * This default implementation is for backward compatibility with the legacy * {@link #aroundStages} and {@link #parallelStages} methods. */ default void beforeStages( @Nonnull Stage parent, @Nonnull StageGraphBuilder graph ) { List<Stage> stages = aroundStages(parent) .stream() .filter((it) -> it.getSyntheticStageOwner() == STAGE_BEFORE) .collect(toList()); if (!stages.isEmpty()) { graph.add(stages.get(0)); } for (int i = 1; i < stages.size(); i++) { graph.connect(stages.get(i - 1), stages.get(i)); } parallelStages(parent) .stream() .filter((it) -> it.getSyntheticStageOwner() == STAGE_BEFORE) .forEach(graph::add); }
} else if (parentStageId != null && !visited.contains(parentStageId)) { List<Stage> ancestors = new ArrayList<>(); if (getSyntheticStageOwner() == SyntheticStageOwner.STAGE_AFTER) { ancestors.addAll( execution .stream() .filter(it -> parentStageId.equals(it.parentStageId) && it.getSyntheticStageOwner() == SyntheticStageOwner.STAGE_BEFORE
private String generateRefId() { long offset = parent .getExecution() .getStages() .stream() .filter(i -> parent.getId().equals(i.getParentStageId()) && type == i.getSyntheticStageOwner()) .count(); return format( "%s%s%d", parent.getRefId(), type == STAGE_BEFORE ? "<" : ">", offset + graph.nodes().size() ); }
private void storeStageInternal(RedisClientDelegate delegate, Stage stage, Boolean updateIndex) { String key = executionKey(stage); String indexKey = format("%s:stageIndex", key); Map<String, String> serializedStage = serializeStage(stage); List<String> keysToRemove = serializedStage.entrySet().stream() .filter(e -> e.getValue() == null) .map(Map.Entry::getKey) .collect(Collectors.toList()); serializedStage.values().removeIf(Objects::isNull); delegate.withTransaction(tx -> { tx.hmset(key, serializedStage); if (!keysToRemove.isEmpty()) { tx.hdel(key, keysToRemove.toArray(new String[0])); } if (updateIndex) { BinaryClient.LIST_POSITION pos = stage.getSyntheticStageOwner() == STAGE_BEFORE ? BEFORE : AFTER; tx.linsert(indexKey, pos, stage.getParentStageId(), stage.getId()); } tx.exec(); }); }
s -> { Integer index = execution.getStages().indexOf(s.getParent()); if (s.getSyntheticStageOwner() == STAGE_AFTER) { index++;
map.put(prefix + "startTimeExpiry", stage.getStartTimeExpiry() != null ? String.valueOf(stage.getStartTimeExpiry()) : null); map.put(prefix + "status", stage.getStatus().name()); map.put(prefix + "syntheticStageOwner", stage.getSyntheticStageOwner() != null ? stage.getSyntheticStageOwner().name() : null); map.put(prefix + "parentStageId", stage.getParentStageId()); if (!stage.getRequisiteStageRefIds().isEmpty()) {
/** * A Stage is optional if it has an {@link OptionalStageEvaluator} in its * context that evaluates {@code false}. */ public static boolean isOptional(Stage stage, ContextParameterProcessor contextParameterProcessor) { Map stageEnabled = (Map) stage.getContext().get("stageEnabled"); String type = stageEnabled == null ? null : (String) stageEnabled.get("type"); String optionalType = type == null ? null : type.toLowerCase(); if (!OPTIONAL_STAGE_TYPES.containsKey(optionalType)) { if (stage.getSyntheticStageOwner() != null || stage.getParentStageId() != null) { Stage parentStage = stage .getExecution() .getStages() .stream() .filter(it -> it.getId().equals(stage.getParentStageId())) .findFirst() .orElseThrow(() -> new IllegalStateException(format("stage %s not found", stage.getParentStageId()))); return isOptional(parentStage, contextParameterProcessor); } return false; } try { return !stage.mapTo("/stageEnabled", OPTIONAL_STAGE_TYPES.get(optionalType)).evaluate(stage, contextParameterProcessor); } catch (InvalidExpression e) { log.warn("Unable to determine stage optionality, reason: {} (executionId: {}, stageId: {})", e.getMessage(), stage.getExecution().getId(), stage.getId()); return false; } }