• gradle-5 运行&尾篇


    gradle-5 运行&尾篇

    运行篇

    上篇已经说到有向任务图已经构建完毕,接下来就是对任务进行执行了


    入口

    在这里插入图片描述

    调用链路

    // DefaultGradleLauncher.java
    private void runWork() {
            if (stage != Stage.TaskGraph) {
                throw new IllegalStateException("Cannot execute tasks: current stage = " + stage);
            }
    
            List<Throwable> taskFailures = new ArrayList<>();
            buildExecuter.execute(gradle, taskFailures);
            if (!taskFailures.isEmpty()) {
                throw new MultipleBuildFailures(taskFailures);
            }
    
            stage = Stage.RunTasks;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    buildExecuter对象来源于下图的方法调用,调用层级是由外到内,层层递进关系
    在这里插入图片描述
    BuildOperationFiringBuildWorkerExecutor、DeprecateUndefinedBuildWorkExecutor、IncludedBuildLifecycleBuildWorkExecutor基本都是转发,无决定意义,直接跳过,直接到DefaultBuildWorkExecutor
    在这里插入图片描述
    最终还是依次执行executionActions容器对象,上面可以看到构造器传入了二个action,只要分析它就好了

    二个action

    执行taskGraph中的task前会执行二个action

    DryRunBuildExecutionAction

    针对dry-run特殊处理,主要就是一些打印输出

    /**
     * A {@link org.gradle.execution.BuildExecutionAction} that disables all selected tasks before they are executed.
     */
    public class DryRunBuildExecutionAction implements BuildExecutionAction {
        private final StyledTextOutputFactory textOutputFactory;
    
        public DryRunBuildExecutionAction(StyledTextOutputFactory textOutputFactory) {
            this.textOutputFactory = textOutputFactory;
        }
    
        @Override
        public void execute(BuildExecutionContext context, Collection<? super Throwable> taskFailures) {
            GradleInternal gradle = context.getGradle();
            if (gradle.getStartParameter().isDryRun()) {
                for (Task task : gradle.getTaskGraph().getAllTasks()) {
                    textOutputFactory.create(DryRunBuildExecutionAction.class)
                        .append(((TaskInternal) task).getIdentityPath().getPath())
                        .append(" ")
                        .style(StyledTextOutput.Style.ProgressStatus)
                        .append("SKIPPED")
                        .println();
                }
            } else {
                context.proceed();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    SelectedTaskExecutionAction

    主要是绑定规则,具体不太清楚干什么用的

    public class SelectedTaskExecutionAction implements BuildExecutionAction {
        @Override
        public void execute(BuildExecutionContext context, Collection<? super Throwable> taskFailures) {
            GradleInternal gradle = context.getGradle();
            TaskExecutionGraphInternal taskGraph = gradle.getTaskGraph();
          
          	// 设置当任务执行失败是,是否继续下去
            if (gradle.getStartParameter().isContinueOnFailure()) {
                taskGraph.setContinueOnFailure(true);
            }
    
            bindAllReferencesOfProject(taskGraph);
          
          	// 执行任务(DefaultTaskExecutionGraph)
            taskGraph.execute(taskFailures);
        }
    
        private void bindAllReferencesOfProject(TaskExecutionGraph graph) {
            Set<Project> seen = Sets.newHashSet();
            for (Task task : graph.getAllTasks()) {
                if (seen.add(task.getProject())) {
                    ProjectInternal projectInternal = (ProjectInternal) task.getProject();
                  	//绑定规则?
                    projectInternal.bindAllModelRules();
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    run taskGraph

    DefaultTaskExecutionGraph

    @Override
        public void execute(Collection<? super Throwable> failures) {
            if (!hasFiredWhenReady) {
                throw new IllegalStateException("Task graph should be populated before execution starts.");
            }
            try (ProjectExecutionServiceRegistry projectExecutionServices = new ProjectExecutionServiceRegistry(globalServices)) {
                executeWithServices(projectExecutionServices, failures);
            }
        }
    
    private void executeWithServices(ProjectExecutionServiceRegistry projectExecutionServices, Collection<? super Throwable> failures) {
            Timer clock = Time.startTimer();
            try {
              	// DefaultPlanExecutor
                planExecutor.process(
                    executionPlan,
                    failures,
                    new BuildOperationAwareExecutionAction(
                        buildOperationExecutor.getCurrentOperation(),
                        new InvokeNodeExecutorsAction(nodeExecutors, projectExecutionServices)
                    )
                );
                LOGGER.debug("Timing: Executing the DAG took " + clock.getElapsed());
            } finally {
                coordinationService.withStateLock(resourceLockState -> {
                    executionPlan.clear();
                    return ResourceLockState.Disposition.FINISHED;
                });
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    后面的调用层级非常深,最终会经过多个任务执行器()执行
    在这里插入图片描述
    EventFiringTaskExecuter:事项通知发送包括beforeExecuteafterExecute
    CatchExceptionTaskExecuter:异常处理
    SkipOnlyIfTaskExecuter: 针对onlyif特殊谓词的task直接skip onlyif官方说明
    SkipTaskWithNoActionsExecuter:无action的task不会执行
    ResolveTaskExecutionModeExecuter:设置任务执行模式(5种),执行会有差异
    在这里插入图片描述
    FinalizePropertiesTaskExecuter:任务预处理,结束事件调用
    CleanupStaleOutputsExecuter:Clean stale outputs
    ExecuteActionsTaskExecuter:任务执行

    尾篇

    入口

    在这里插入图片描述

    代码实现

    private void finishBuild(String action, @Nullable Throwable stageFailure) {
            if (stage == Stage.Finished) {
                return;
            }
    
            RuntimeException reportableFailure = stageFailure == null ? null : exceptionAnalyser.transform(stageFailure);
            BuildResult buildResult = new BuildResult(action, gradle, reportableFailure);
            List<Throwable> failures = new ArrayList<>();
      
      			// 任务执行器对应的线程回收
            includedBuildControllers.finishBuild(failures);
      
      			// 相关回调调用
            try {
                buildListener.buildFinished(buildResult);
                buildFinishedListener.buildFinished((GradleInternal) buildResult.getGradle());
            } catch (Throwable t) {
                failures.add(t);
            }
            stage = Stage.Finished;
    
            if (failures.isEmpty() && reportableFailure != null) {
                throw reportableFailure;
            }
            if (!failures.isEmpty()) {
                if (stageFailure instanceof MultipleBuildFailures) {
                    failures.addAll(0, ((MultipleBuildFailures) stageFailure).getCauses());
                } else if (stageFailure != null) {
                    failures.add(0, stageFailure);
                }
                throw exceptionAnalyser.transform(new MultipleBuildFailures(failures));
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    小结

    任务执行结束阶段

    1. 资源清理操作;比如buildControllers清理、任务执行线程的停止
    2. 触发buildFinished生命周期方法

    之此gradle系列篇已初探完毕,我们对gradle整个生命周期的内部实现,应该比之前有更深入的理解😄

  • 相关阅读:
    cmake: command not found
    noip2012Vigenère 密码
    【Adobe Illustrator 教程】2. 认识矩形工具并绘制一些马赛克图案
    哪些人群在报考浙大工程管理硕士(MEM)?
    数据安全之翼:天空卫士在汽车数据安全领域的卓越领航
    低代码发展趋势解读|低代码成为企业数字化转型“加速器”
    音频——I2S TDM 模式(六)
    电影主题HTM5网页设计作业成品——爱影评在线电影(10页面)使用dreamweaver制作采用DIV+CSS进行布局
    Doris开发手记4:倍速性能提升,向量化导入的性能调优实践
    大模型如何商业变现?小i机器人发布华藏大模型生态
  • 原文地址:https://blog.csdn.net/dbs1215/article/details/126117087