packageorg.apache.flink.runtime.scheduler;publicclassDefaultSchedulerextendsSchedulerBaseimplementsSchedulerOperations{@OverrideprotectedvoidstartSchedulingInternal(){
log.info("Starting scheduling with scheduling strategy [{}]",
schedulingStrategy.getClass().getName());transitionToRunning();
schedulingStrategy.startScheduling();}
packageorg.apache.flink.runtime.executiongraph;publicclassDefaultExecutionGraphimplementsExecutionGraph,InternalExecutionGraphAccessor{@OverridepublicvoidtransitionToRunning(){if(!transitionState(JobStatus.CREATED,JobStatus.RUNNING)){thrownewIllegalStateException("Job may only be scheduled from state "+JobStatus.CREATED);}}
org.apache.flink.runtime.executiongraph.DefaultExecutionGraphpublicclassDefaultExecutionGraphimplementsExecutionGraph,InternalExecutionGraphAccessor{@OverridepublicbooleantransitionState(JobStatus current,JobStatus newState){returntransitionState(current, newState,null);}privatebooleantransitionState(JobStatus current,JobStatus newState,Throwable error){assertRunningInJobMasterMainThread();// consistency checkif(current.isTerminalState()){String message ="Job is trying to leave terminal state "+ current;LOG.error(message);thrownewIllegalStateException(message);}// now do the actual state transitionif(state == current){
state = newState;LOG.info("Job {} ({}) switched from state {} to {}.",getJobName(),getJobID(),
current,
newState,
error);
stateTimestamps[newState.ordinal()]=System.currentTimeMillis();notifyJobStatusChange(newState);returntrue;}else{returnfalse;}}privatevoidnotifyJobStatusChange(JobStatus newState){if(jobStatusListeners.size()>0){finallong timestamp =System.currentTimeMillis();for(JobStatusListener listener : jobStatusListeners){try{
listener.jobStatusChanges(getJobID(), newState, timestamp);}catch(Throwable t){LOG.warn("Error while notifying JobStatusListener", t);}}}}
packageorg.apache.flink.runtime.checkpoint.CheckpointCoordinatorDeActivatorpublicvoidjobStatusChanges(JobID jobId,JobStatus newJobStatus,long timestamp){if(newJobStatus ==JobStatus.RUNNING){// start the checkpoint scheduler
coordinator.startCheckpointScheduler();}else{// anything else should stop the trigger for now
coordinator.stopCheckpointScheduler();}}
packageorg.apache.flink.runtime.checkpointpublicclassCheckpointCoordinator{publicvoidstartCheckpointScheduler(){synchronized(lock){if(shutdown){thrownewIllegalArgumentException("Checkpoint coordinator is shut down");}Preconditions.checkState(isPeriodicCheckpointingConfigured(),"Can not start checkpoint scheduler, if no periodic checkpointing is configured");// make sure all prior timers are cancelledstopCheckpointScheduler();
periodicScheduling =true;
currentPeriodicTrigger =scheduleTriggerWithDelay(getRandomInitDelay());privateScheduledFuture<?>scheduleTriggerWithDelay(long initDelay){return timer.scheduleAtFixedRate(newScheduledTrigger(), initDelay, baseInterval,TimeUnit.MILLISECONDS);}privatefinalclassScheduledTriggerimplementsRunnable{@Overridepublicvoidrun(){try{triggerCheckpoint(true);}catch(Exception e){LOG.error("Exception while triggering checkpoint for job {}.", job, e);}}}@VisibleForTestingpublicCompletableFuture<CompletedCheckpoint>triggerCheckpoint(CheckpointProperties props,@NullableString externalSavepointLocation,boolean isPeriodic){CheckpointTriggerRequest request =newCheckpointTriggerRequest(props, externalSavepointLocation, isPeriodic);chooseRequestToExecute(request).ifPresent(this::startTriggeringCheckpoint);return request.onCompletionPromise;}privatevoidstartTriggeringCheckpoint(CheckpointTriggerRequest request){try{synchronized(lock){preCheckGlobalState(request.isPeriodic);}// we will actually trigger this checkpoint!Preconditions.checkState(!isTriggering);
isTriggering =true;finallong timestamp =System.currentTimeMillis();CompletableFuture<CheckpointPlan> checkpointPlanFuture =
checkpointPlanCalculator.calculateCheckpointPlan();boolean initializeBaseLocations =!baseLocationsForCheckpointInitialized;
baseLocationsForCheckpointInitialized =true;CompletableFuture<Void> masterTriggerCompletionPromise =newCompletableFuture<>();finalCompletableFuture<PendingCheckpoint> pendingCheckpointCompletableFuture =
checkpointPlanFuture
.thenApplyAsync(
plan ->{try{// this must happen outside the coordinator-wide lock,// because it communicates with external services// (in HA mode) and may block for a while.long checkpointID =
checkpointIdCounter.getAndIncrement();returnnewTuple2<>(plan, checkpointID);}catch(Throwable e){thrownewCompletionException(e);}},
executor).thenApplyAsync((checkpointInfo)->createPendingCheckpoint(
timestamp,
request.props,
checkpointInfo.f0,
request.isPeriodic,
checkpointInfo.f1,
request.getOnCompletionFuture(),
masterTriggerCompletionPromise),
timer);finalCompletableFuture<?> coordinatorCheckpointsComplete =
pendingCheckpointCompletableFuture
.thenApplyAsync(
pendingCheckpoint ->{try{CheckpointStorageLocation checkpointStorageLocation =initializeCheckpointLocation(
pendingCheckpoint.getCheckpointID(),
request.props,
request.externalSavepointLocation,
initializeBaseLocations);returnTuple2.of(
pendingCheckpoint, checkpointStorageLocation);}catch(Throwable e){thrownewCompletionException(e);}},
executor).thenComposeAsync((checkpointInfo)->{PendingCheckpoint pendingCheckpoint = checkpointInfo.f0;if(pendingCheckpoint.isDisposed()){// The disposed checkpoint will be handled later,// skip snapshotting the coordinator states.returnnull;}synchronized(lock){
pendingCheckpoint.setCheckpointTargetLocation(
checkpointInfo.f1);}returnOperatorCoordinatorCheckpoints.triggerAndAcknowledgeAllCoordinatorCheckpointsWithCompletion(
coordinatorsToCheckpoint,
pendingCheckpoint,
timer);},
timer);// We have to take the snapshot of the master hooks after the coordinator checkpoints// has completed.// This is to ensure the tasks are checkpointed after the OperatorCoordinators in case// ExternallyInducedSource is used.finalCompletableFuture<?> masterStatesComplete =
coordinatorCheckpointsComplete.thenComposeAsync(
ignored ->{// If the code reaches here, the pending checkpoint is guaranteed to// be not null.// We use FutureUtils.getWithoutException() to make compiler happy// with checked// exceptions in the signature.PendingCheckpoint checkpoint =FutureUtils.getWithoutException(
pendingCheckpointCompletableFuture);if(checkpoint ==null|| checkpoint.isDisposed()){// The disposed checkpoint will be handled later,// skip snapshotting the master states.returnnull;}returnsnapshotMasterState(checkpoint);},
timer);FutureUtils.forward(CompletableFuture.allOf(masterStatesComplete, coordinatorCheckpointsComplete),
masterTriggerCompletionPromise);FutureUtils.assertNoException(
masterTriggerCompletionPromise
.handleAsync((ignored, throwable)->{finalPendingCheckpoint checkpoint =FutureUtils.getWithoutException(
pendingCheckpointCompletableFuture);Preconditions.checkState(
checkpoint !=null|| throwable !=null,"Either the pending checkpoint needs to be created or an error must have occurred.");if(throwable !=null){// the initialization might not be finished yetif(checkpoint ==null){onTriggerFailure(request, throwable);}else{onTriggerFailure(checkpoint, throwable);}}else{triggerCheckpointRequest(
request, timestamp, checkpoint);}returnnull;},
timer).exceptionally(
error ->{if(!isShutdown()){thrownewCompletionException(error);}elseif(findThrowable(
error,RejectedExecutionException.class).isPresent()){LOG.debug("Execution rejected during shutdown");}else{LOG.warn("Error encountered during shutdown", error);}returnnull;}));}catch(Throwable throwable){onTriggerFailure(request, throwable);}}privatevoidtriggerCheckpointRequest(CheckpointTriggerRequest request,long timestamp,PendingCheckpoint checkpoint){if(checkpoint.isDisposed()){onTriggerFailure(
checkpoint,newCheckpointException(CheckpointFailureReason.TRIGGER_CHECKPOINT_FAILURE,
checkpoint.getFailureCause()));}else{triggerTasks(request, timestamp, checkpoint).exceptionally(
failure ->{LOG.info("Triggering Checkpoint {} for job {} failed due to {}",
checkpoint.getCheckpointID(),
job,
failure);finalCheckpointException cause;if(failure instanceofCheckpointException){
cause =(CheckpointException) failure;}else{
cause =newCheckpointException(CheckpointFailureReason.TRIGGER_CHECKPOINT_FAILURE,
failure);}
timer.execute(()->{synchronized(lock){abortPendingCheckpoint(checkpoint, cause);}});returnnull;});
coordinatorsToCheckpoint.forEach((ctx)-> ctx.afterSourceBarrierInjection(checkpoint.getCheckpointID()));// It is possible that the tasks has finished// checkpointing at this point.// So we need to complete this pending checkpoint.if(maybeCompleteCheckpoint(checkpoint)){onTriggerSuccess();}}}privateCompletableFuture<Void>triggerTasks(CheckpointTriggerRequest request,long timestamp,PendingCheckpoint checkpoint){// no exception, no discarding, everything is OKfinallong checkpointId = checkpoint.getCheckpointID();finalSnapshotType type;if(this.forceFullSnapshot &&!request.props.isSavepoint()){
type =CheckpointType.FULL_CHECKPOINT;}else{
type = request.props.getCheckpointType();}finalCheckpointOptions checkpointOptions =CheckpointOptions.forConfig(
type,
checkpoint.getCheckpointStorageLocation().getLocationReference(),
isExactlyOnceMode,
unalignedCheckpointsEnabled,
alignedCheckpointTimeout);// send messages to the tasks to trigger their checkpointsList<CompletableFuture<Acknowledge>> acks =newArrayList<>();for(Execution execution : checkpoint.getCheckpointPlan().getTasksToTrigger()){if(request.props.isSynchronous()){
acks.add(
execution.triggerSynchronousSavepoint(
checkpointId, timestamp, checkpointOptions));}else{
acks.add(execution.triggerCheckpoint(checkpointId, timestamp, checkpointOptions));}}returnFutureUtils.waitForAll(acks);}