}
@Override
public Update newUpdate(IJobUpdateInstructions instructions, boolean rollingForward) {
requireNonNull(instructions);
IJobUpdateSettings settings = instructions.getSettings();
checkArgument(
settings.getMaxWaitToInstanceRunningMs() > 0,
"Max wait to running must be positive.");
checkArgument(
settings.getMinWaitInInstanceRunningMs() > 0,
"Min wait in running must be positive.");
checkArgument(
settings.getUpdateGroupSize() > 0,
"Update group size must be positive.");
Set<Integer> instances;
Set<Integer> desiredInstances = instructions.isSetDesiredState()
? expandInstanceIds(ImmutableSet.of(instructions.getDesiredState()))
: ImmutableSet.<Integer>of();
if (settings.getUpdateOnlyTheseInstances().isEmpty()) {
// In a full job update, the working set is the union of instance IDs before and after.
instances = ImmutableSet.copyOf(
Sets.union(expandInstanceIds(instructions.getInitialState()), desiredInstances));
} else {
instances = Numbers.rangesToInstanceIds(settings.getUpdateOnlyTheseInstances());
}
ImmutableMap.Builder<Integer, StateEvaluator<Optional<IScheduledTask>>> evaluators =
ImmutableMap.builder();
for (int instanceId : instances) {
Optional<ITaskConfig> desiredStateConfig;
if (rollingForward) {
desiredStateConfig = desiredInstances.contains(instanceId)
? Optional.of(instructions.getDesiredState().getTask())
: Optional.<ITaskConfig>absent();
} else {
desiredStateConfig = getConfig(instanceId, instructions.getInitialState());
}
evaluators.put(
instanceId,
new InstanceUpdater(
desiredStateConfig,
settings.getMaxPerInstanceFailures(),
Amount.of((long) settings.getMinWaitInInstanceRunningMs(), Time.MILLISECONDS),
Amount.of((long) settings.getMaxWaitToInstanceRunningMs(), Time.MILLISECONDS),
clock));
}
Ordering<Integer> updateOrder = rollingForward
? Ordering.<Integer>natural()
: Ordering.<Integer>natural().reverse();
UpdateStrategy<Integer> strategy = settings.isWaitForBatchCompletion()
? new BatchStrategy<>(updateOrder, settings.getUpdateGroupSize())
: new QueueStrategy<>(updateOrder, settings.getUpdateGroupSize());
JobUpdateStatus successStatus =
rollingForward ? JobUpdateStatus.ROLLED_FORWARD : JobUpdateStatus.ROLLED_BACK;
JobUpdateStatus failureStatus = rollingForward && settings.isRollbackOnFailure()
? JobUpdateStatus.ROLLING_BACK
: JobUpdateStatus.FAILED;
return new Update(
new OneWayJobUpdater<>(
strategy,
settings.getMaxFailedInstances(),
evaluators.build()),
successStatus,
failureStatus);
}