// Attempt to connect to an existing idle and compatible daemon intsaneNumberOfAttempts=100; //is it sane enough? for (inti=1; i < saneNumberOfAttempts; i++) { finalDaemonClientConnectionconnection= connector.connect(compatibilitySpec); // No existing, compatible daemon is available to try if (connection == null) { break; } // Compatible daemon was found, try it try { Buildbuild=newBuild(buildId, connection.getDaemon().getToken(), action, requestContext.getClient(), requestContext.getStartTime(), requestContext.isInteractive(), parameters); return executeBuild(build, connection, requestContext.getCancellationToken(), requestContext.getEventConsumer()); } catch (DaemonInitialConnectException e) { // this exception means that we want to try again. LOGGER.debug("{}, Trying a different daemon...", e.getMessage()); accumulatedExceptions.add(e); } finally { connection.stop(); } }
// No existing daemon was usable, so start a new one and try it once finalDaemonClientConnectionconnection= connector.startDaemon(compatibilitySpec); try { Buildbuild=newBuild(buildId, connection.getDaemon().getToken(), action, requestContext.getClient(), requestContext.getStartTime(), requestContext.isInteractive(), parameters); return executeBuild(build, connection, requestContext.getCancellationToken(), requestContext.getEventConsumer()); } catch (DaemonInitialConnectException e) { //...... } finally { connection.stop(); } }
创建Process
DefaultDaemonConnector.java
1 2 3
public DaemonClientConnection startDaemon(ExplainingSpec<DaemonContext> constraint) { return doStartDaemon(constraint, false); }
public DaemonStartupInfo startDaemon(boolean singleUse) { StringdaemonUid= UUID.randomUUID().toString(); // 获取必要的参数信息 GradleInstallationgradleInstallation= CurrentGradleInstallation.get(); ModuleRegistryregistry=newDefaultModuleRegistry(gradleInstallation); ClassPath classpath; List<File> searchClassPath; if (gradleInstallation == null) { // When not running from a Gradle distro, need runtime impl for launcher plus the search path to look for other modules classpath = registry.getModule("gradle-launcher").getAllRequiredModulesClasspath(); searchClassPath = registry.getAdditionalClassPath().getAsFiles(); } else { // When running from a Gradle distro, only need launcher jar. The daemon can find everything from there. classpath = registry.getModule("gradle-launcher").getImplementationClasspath(); searchClassPath = Collections.emptyList(); } if (classpath.isEmpty()) { thrownewIllegalStateException("Unable to construct a bootstrap classpath when starting the daemon"); }
if (Boolean.getBoolean("org.gradle.daemon.debug")) { daemonArgs.add("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"); } LOGGER.debug("Using daemon args: {}", daemonArgs);
daemonArgs.add(GradleDaemon.class.getName()); // Version isn't used, except by a human looking at the output of jps. daemonArgs.add(GradleVersion.current().getVersion());
// This factory should be injected but leaves non-daemon threads running when used from the tooling API client @SuppressWarnings("deprecation") DefaultExecActionFactoryexecActionFactory= DefaultExecActionFactory.root(gradleUserHome); try { // 配置启动参数 ExecHandlehandle=newDaemonExecHandleBuilder().build(args, workingDir, outputConsumer, stdInput, execActionFactory.newExec()); // 执行 handle.start(); LOGGER.debug("Gradle daemon process is starting. Waiting for the daemon to detach..."); // 等待结束 handle.waitForFinish(); LOGGER.debug("Gradle daemon process is now detached."); } finally { CompositeStoppable.stoppable(execActionFactory).stop(); } // 解析启动结果 return daemonGreeter.parseDaemonOutput(outputConsumer.getProcessOutput(), args); } catch (GradleException e) { throw e; } catch (Exception e) { thrownewGradleException("Could not start Gradle daemon.", e); } finally { LOGGER.info("An attempt to start the daemon took {}.", clock.getElapsed()); } }