上一篇博客

18. Gradle編譯其他應(yīng)用代碼流程(六) - 執(zhí)行Task過(guò)程
一. 守護(hù)進(jìn)程的作用
守護(hù)進(jìn)程就是一個(gè)用來(lái)構(gòu)建的其他進(jìn)程。
從前幾篇文章我們知道gradle編譯的時(shí)候會(huì)加載各種所需要的Jar,加載這些Jar是需要時(shí)間的。
如果我們之前有守護(hù)進(jìn)程編譯過(guò)其他程序,而這個(gè)進(jìn)程沒(méi)有被kill掉,那么是可以重用這個(gè)守護(hù)進(jìn)程的。
二. 選擇守護(hù)進(jìn)程編譯
選擇守護(hù)進(jìn)程編譯的策略是
如果守護(hù)進(jìn)程存在,那么就使用守護(hù)進(jìn)程編譯。
否則,如果可以在當(dāng)前進(jìn)程編譯,那么就在當(dāng)前進(jìn)程編譯。
否則,啟動(dòng)新的守護(hù)進(jìn)程來(lái)編譯。
代碼如下:
class BuildActionsFactory implements CommandLineAction {
public Runnable createAction(CommandLineParser parser, ParsedCommandLine commandLine) {
...
if (parameters.getDaemonParameters().isEnabled()) {
return runBuildWithDaemon(parameters.getStartParameter(), parameters.getDaemonParameters(), loggingServices);
}
if (canUseCurrentProcess(parameters.getDaemonParameters())) {
return runBuildInProcess(parameters.getStartParameter(), parameters.getDaemonParameters(), loggingServices);
}
return runBuildInSingleUseDaemon(parameters.getStartParameter(), parameters.getDaemonParameters(), loggingServices);
}
}三. 啟動(dòng)守護(hù)進(jìn)程的入口
public class DefaultDaemonStarter implements DaemonStarter {
....
public DaemonStartupInfo startDaemon() {
String daemonUid = UUID.randomUUID().toString();
GradleInstallation gradleInstallation = CurrentGradleInstallation.get();
ModuleRegistry registry = new DefaultModuleRegistry(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 = new DefaultClassPath();
for (Module module : registry.getModule("gradle-launcher").getAllRequiredModules()) {
classpath = classpath.plus(module.getClasspath());
}
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()) {
throw new IllegalStateException("Unable to construct a bootstrap classpath when starting the daemon");
}
versionValidator.validate(daemonParameters);
List<String> daemonArgs = new ArrayList<String>();
daemonArgs.add(daemonParameters.getEffectiveJvm().getJavaExecutable().getAbsolutePath());
List<String> daemonOpts = daemonParameters.getEffectiveJvmArgs();
daemonArgs.addAll(daemonOpts);
daemonArgs.add("-cp");
daemonArgs.add(CollectionUtils.join(File.pathSeparator, classpath.getAsFiles()));
if (Boolean.getBoolean("org.gradle.daemon.debug")) {
daemonArgs.add("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005");
}
daemonArgs.add(GradleDaemon.class.getName());
// Version isn't used, except by a human looking at the output of jps.
daemonArgs.add(GradleVersion.current().getVersion());
// Serialize configuration to daemon via the process' stdin
ByteArrayOutputStream serializedConfig = new ByteArrayOutputStream();
FlushableEncoder encoder = new KryoBackedEncoder(new EncodedStream.EncodedOutput(serializedConfig));
try {
encoder.writeString(daemonParameters.getGradleUserHomeDir().getAbsolutePath());
encoder.writeString(daemonDir.getBaseDir().getAbsolutePath());
encoder.writeSmallInt(daemonParameters.getIdleTimeout());
encoder.writeSmallInt(daemonParameters.getPeriodicCheckInterval());
encoder.writeString(daemonUid);
encoder.writeSmallInt(daemonOpts.size());
for (String daemonOpt : daemonOpts) {
encoder.writeString(daemonOpt);
}
encoder.writeSmallInt(searchClassPath.size());
for (File file : searchClassPath) {
encoder.writeString(file.getAbsolutePath());
}
encoder.flush();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
ByteArrayInputStream stdInput = new ByteArrayInputStream(serializedConfig.toByteArray());
return startProcess(daemonArgs, daemonDir.getVersionedDir(), stdInput);
}四. 守護(hù)進(jìn)程執(zhí)行入口
public class GradleDaemon {
public static void main(String[] args) {
new ProcessBootstrap().run("org.gradle.launcher.daemon.bootstrap.DaemonMain", args);
}
}
public class DaemonMain extends EntryPoint {
private static final Logger LOGGER = Logging.getLogger(DaemonMain.class);
private PrintStream originalOut;
private PrintStream originalErr;
@Override
protected void doAction(String[] args, ExecutionListener listener) {
...
KryoBackedDecoder decoder = new KryoBackedDecoder(new EncodedStream.EncodedInput(System.in));
try {
gradleHomeDir = new File(decoder.readString());
daemonBaseDir = new File(decoder.readString());
idleTimeoutMs = decoder.readSmallInt();
periodicCheckIntervalMs = decoder.readSmallInt();
daemonUid = decoder.readString();
int argCount = decoder.readSmallInt();
startupOpts = new ArrayList<String>(argCount);
for (int i = 0; i < argCount; i++) {
startupOpts.add(decoder.readString());
}
int additionalClassPathLength = decoder.readSmallInt();
additionalClassPath = new ArrayList<File>(additionalClassPathLength);
for (int i = 0; i < additionalClassPathLength; i++) {
additionalClassPath.add(new File(decoder.readString()));
}
} catch (EOFException e) {
System.out.println("DaemonMain doAction 4");
throw new UncheckedIOException(e);
}
NativeServices.initialize(gradleHomeDir);
DaemonServerConfiguration parameters = new DefaultDaemonServerConfiguration(daemonUid, daemonBaseDir, idleTimeoutMs, periodicCheckIntervalMs, startupOpts);
LoggingServiceRegistry loggingRegistry = LoggingServiceRegistry.newCommandLineProcessLogging();
LoggingManagerInternal loggingManager = loggingRegistry.newInstance(LoggingManagerInternal.class);
TrueTimeProvider timeProvider = new TrueTimeProvider();
DaemonServices daemonServices = new DaemonServices(parameters, loggingRegistry, loggingManager, new DefaultClassPath(additionalClassPath), timeProvider.getCurrentTime());
File daemonLog = daemonServices.getDaemonLogFile();
// Any logging prior to this point will not end up in the daemon log file.
initialiseLogging(loggingManager, daemonLog);
LOGGER.debug("Assuming the daemon was started with following jvm opts: {}", startupOpts);
Daemon daemon = daemonServices.get(Daemon.class);
daemon.start();
try {
DaemonContext daemonContext = daemonServices.get(DaemonContext.class);
Long pid = daemonContext.getPid();
daemonStarted(pid, daemon.getUid(), daemon.getAddress(), daemonLog);
DaemonExpirationStrategy expirationStrategy = daemonServices.get(MasterExpirationStrategy.class);
daemon.stopOnExpiration(expirationStrategy, parameters.getPeriodicCheckIntervalMs());
} finally {
daemon.stop();
}
}
}五. 守護(hù)進(jìn)程的日志
守護(hù)進(jìn)程的日志沒(méi)有打印在控制臺(tái),而是打印在文件中,通過(guò)下面這行代碼,進(jìn)行了日志輸出流轉(zhuǎn)向。
// Any logging prior to this point will not end up in the daemon log file. initialiseLogging(loggingManager, daemonLog);
日志保存的位置在 GRADLE_USER_HOME/daemon/版本號(hào)/daemon-進(jìn)程號(hào).out.log
如果沒(méi)有配置GRADLE_USER_HOME,那就在根目錄。windows的話在'c:\Users\rongwei.huang\.gradle\'
我自己的日志目錄是:"d:\gradle_jar_cache\daemon\3.1-snapshot-1\daemon-10972.out.log"
最后附加自己編譯的gradle3.1源代碼和編譯生成文件
gradle3.1源代碼
gradle3.1源代碼編譯后文件
創(chuàng)新互聯(lián)www.cdcxhl.cn,專(zhuān)業(yè)提供香港、美國(guó)云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開(kāi)啟,新人活動(dòng)云服務(wù)器買(mǎi)多久送多久。
新聞標(biāo)題:20.Gradle編譯其他應(yīng)用代碼流程(七)-守護(hù)進(jìn)程編譯-創(chuàng)新互聯(lián)
文章來(lái)源:http://www.yijiale78.com/article34/ceihse.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供做網(wǎng)站、Google、網(wǎng)站導(dǎo)航、品牌網(wǎng)站制作、網(wǎng)站排名、網(wǎng)站設(shè)計(jì)公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容