use of com.facebook.presto.execution.scheduler.ScheduleResult.BlockedReason in project presto by prestodb.
the class FixedSourcePartitionedScheduler method schedule.
@Override
public ScheduleResult schedule() {
// schedule a task on every node in the distribution
List<RemoteTask> newTasks = ImmutableList.of();
if (!scheduledTasks) {
newTasks = Streams.mapWithIndex(nodes.stream(), (node, id) -> stage.scheduleTask(node, toIntExact(id))).filter(Optional::isPresent).map(Optional::get).collect(toImmutableList());
scheduledTasks = true;
// notify listeners that we have scheduled all tasks so they can set no more buffers or exchange splits
stage.transitionToFinishedTaskScheduling();
}
boolean allBlocked = true;
List<ListenableFuture<?>> blocked = new ArrayList<>();
BlockedReason blockedReason = BlockedReason.NO_ACTIVE_DRIVER_GROUP;
if (groupedLifespanScheduler.isPresent()) {
while (!tasksToRecover.isEmpty()) {
if (anySourceSchedulingFinished) {
throw new IllegalStateException("Recover after any source scheduling finished is not supported");
}
groupedLifespanScheduler.get().onTaskFailed(tasksToRecover.poll(), sourceSchedulers);
}
if (groupedLifespanScheduler.get().allLifespanExecutionFinished()) {
for (SourceScheduler sourceScheduler : sourceSchedulers) {
sourceScheduler.notifyAllLifespansFinishedExecution();
}
} else {
// Start new driver groups on the first scheduler if necessary,
// i.e. when previous ones have finished execution (not finished scheduling).
//
// Invoke schedule method to get a new SettableFuture every time.
// Reusing previously returned SettableFuture could lead to the ListenableFuture retaining too many listeners.
blocked.add(groupedLifespanScheduler.get().schedule(sourceSchedulers.get(0)));
}
}
int splitsScheduled = 0;
Iterator<SourceScheduler> schedulerIterator = sourceSchedulers.iterator();
List<Lifespan> driverGroupsToStart = ImmutableList.of();
while (schedulerIterator.hasNext()) {
synchronized (this) {
// prevent that by checking if scheduling has been cancelled first.
if (closed) {
break;
}
SourceScheduler sourceScheduler = schedulerIterator.next();
for (Lifespan lifespan : driverGroupsToStart) {
sourceScheduler.startLifespan(lifespan, partitionHandleFor(lifespan));
}
ScheduleResult schedule = sourceScheduler.schedule();
if (schedule.getSplitsScheduled() > 0) {
stage.transitionToSchedulingSplits();
}
splitsScheduled += schedule.getSplitsScheduled();
if (schedule.getBlockedReason().isPresent()) {
blocked.add(schedule.getBlocked());
blockedReason = blockedReason.combineWith(schedule.getBlockedReason().get());
} else {
verify(schedule.getBlocked().isDone(), "blockedReason not provided when scheduler is blocked");
allBlocked = false;
}
driverGroupsToStart = sourceScheduler.drainCompletelyScheduledLifespans();
if (schedule.isFinished()) {
stage.schedulingComplete(sourceScheduler.getPlanNodeId());
sourceSchedulers.remove(sourceScheduler);
sourceScheduler.close();
anySourceSchedulingFinished = true;
}
}
}
if (allBlocked) {
return ScheduleResult.blocked(sourceSchedulers.isEmpty(), newTasks, whenAnyComplete(blocked), blockedReason, splitsScheduled);
} else {
return ScheduleResult.nonBlocked(sourceSchedulers.isEmpty(), newTasks, splitsScheduled);
}
}
Aggregations