/** * NOTE: This method only throws exceptions if it is in an illegal state to be scheduled, or if * the tasks needs to be scheduled immediately and no resource is available. If the task is * accepted by the schedule, any error sets the vertex state to failed and triggers the recovery * logic. * * @param scheduler The scheduler to use to schedule this execution attempt. * @param queued Flag to indicate whether the scheduler may queue this task if it cannot * immediately deploy it. * @throws IllegalStateException Thrown, if the vertex is not in CREATED state, which is the only * state that permits scheduling. * @throws NoResourceAvailableException Thrown is no queued scheduling is allowed and no resources * are currently available. */ public boolean scheduleForExecution(Scheduler scheduler, boolean queued) throws NoResourceAvailableException { if (scheduler == null) { throw new IllegalArgumentException("Cannot send null Scheduler when scheduling execution."); } final SlotSharingGroup sharingGroup = vertex.getJobVertex().getSlotSharingGroup(); final CoLocationConstraint locationConstraint = vertex.getLocationConstraint(); // sanity check if (locationConstraint != null && sharingGroup == null) { throw new RuntimeException( "Trying to schedule with co-location constraint but without slot sharing allowed."); } if (transitionState(CREATED, SCHEDULED)) { ScheduledUnit toSchedule = locationConstraint == null ? new ScheduledUnit(this, sharingGroup) : new ScheduledUnit(this, sharingGroup, locationConstraint); // IMPORTANT: To prevent leaks of cluster resources, we need to make sure that slots are // returned // in all cases where the deployment failed. we use many try {} finally {} clauses to // assure that if (queued) { SlotAllocationFuture future = scheduler.scheduleQueued(toSchedule); future.setFutureAction( new SlotAllocationFutureAction() { @Override public void slotAllocated(SimpleSlot slot) { try { deployToSlot(slot); } catch (Throwable t) { try { slot.releaseSlot(); } finally { markFailed(t); } } } }); } else { SimpleSlot slot = scheduler.scheduleImmediately(toSchedule); try { deployToSlot(slot); } catch (Throwable t) { try { slot.releaseSlot(); } finally { markFailed(t); } } } return true; } else { // call race, already deployed, or already done return false; } }