diff --git a/subprojects/docs/src/docs/release/notes.md b/subprojects/docs/src/docs/release/notes.md index b866eb68f0f2..b714ac887e42 100644 --- a/subprojects/docs/src/docs/release/notes.md +++ b/subprojects/docs/src/docs/release/notes.md @@ -70,6 +70,11 @@ Here are the new features introduced in this Gradle release. IMPORTANT: if this is a patch release, ensure that a prominent link is included in the foreword to all releases of the same minor stream. Add--> +### Starting Gradle as a lower priority process + +You can now use the `--priority low` command line argument or `org.gradle.priority=low` property to start Gradle as a low priority process. +This ensures that other applications like your IDE or browser stay responsive, even while a very demanding build is running. + ### Build init plugin improvements This release includes a number of improvements to The [Build Init plugin](userguide/build_init_plugin.html). diff --git a/subprojects/docs/src/docs/userguide/build_environment.adoc b/subprojects/docs/src/docs/userguide/build_environment.adoc index fe44827e1cd5..bd041bbb02ab 100644 --- a/subprojects/docs/src/docs/userguide/build_environment.adoc +++ b/subprojects/docs/src/docs/userguide/build_environment.adoc @@ -66,6 +66,8 @@ When configured, Gradle will fork up to `org.gradle.workers.max` JVMs to execute When set to `all`, `summary` or `none`, Gradle will use different warning type display. See <> for details. `org.gradle.workers.max=(max # of worker processes)`:: When configured, Gradle will use a maximum of the given number of workers. Default is number of CPU processors. See also <>. +`org.gradle.priority=(low,normal)`:: +Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Default is `normal`. See also <>. The following example demonstrates usage of various properties. diff --git a/subprojects/docs/src/docs/userguide/command_line_interface.adoc b/subprojects/docs/src/docs/userguide/command_line_interface.adoc index 4a2b58bc4c4f..109b86a7265a 100644 --- a/subprojects/docs/src/docs/userguide/command_line_interface.adoc +++ b/subprojects/docs/src/docs/userguide/command_line_interface.adoc @@ -340,6 +340,9 @@ Sets maximum number of workers that Gradle may use. _Default is number of proces `--parallel`, `--no-parallel`:: Build projects in parallel. For limitations of this option, see <>. _Default is off_. +`--priority`:: +Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Values are `normal` or `low`. _Default is normal_. + `--profile`:: Generates a high-level performance report in the `$buildDir/reports/profile` directory. `--scan` is preferred. diff --git a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/daemon/DaemonContextParser.java b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/daemon/DaemonContextParser.java index 1e21daaa67cc..d80ba2c7ebeb 100644 --- a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/daemon/DaemonContextParser.java +++ b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/daemon/DaemonContextParser.java @@ -18,6 +18,7 @@ import com.google.common.base.Splitter; import com.google.common.collect.Lists; +import org.gradle.launcher.daemon.configuration.DaemonParameters; import org.gradle.launcher.daemon.context.DaemonContext; import org.gradle.launcher.daemon.context.DefaultDaemonContext; @@ -57,7 +58,7 @@ public static DaemonContext parseFromString(String source) { } private static DaemonContext parseFrom(String source) { - Pattern pattern = Pattern.compile("^.*DefaultDaemonContext\\[(uid=[^\\n,]+)?,?javaHome=([^\\n]+),daemonRegistryDir=([^\\n]+),pid=([^\\n]+),idleTimeout=(.+?),daemonOpts=([^\\n]+)].*", + Pattern pattern = Pattern.compile("^.*DefaultDaemonContext\\[(uid=[^\\n,]+)?,?javaHome=([^\\n]+),daemonRegistryDir=([^\\n]+),pid=([^\\n]+),idleTimeout=(.+?)(,priority=[^\\n]+)?,daemonOpts=([^\\n]+)].*", Pattern.MULTILINE + Pattern.DOTALL); Matcher matcher = pattern.matcher(source); @@ -68,8 +69,9 @@ private static DaemonContext parseFrom(String source) { String pidStr = matcher.group(4); Long pid = pidStr.equals("null") ? null : Long.parseLong(pidStr); Integer idleTimeout = Integer.decode(matcher.group(5)); - List jvmOpts = Lists.newArrayList(Splitter.on(',').split(matcher.group(6))); - return new DefaultDaemonContext(uid, new File(javaHome), new File(daemonRegistryDir), pid, idleTimeout, jvmOpts); + DaemonParameters.Priority priority = matcher.group(6) == null ? DaemonParameters.Priority.NORMAL : DaemonParameters.Priority.valueOf(matcher.group(6).substring(",priority=".length())); + List jvmOpts = Lists.newArrayList(Splitter.on(',').split(matcher.group(7))); + return new DefaultDaemonContext(uid, new File(javaHome), new File(daemonRegistryDir), pid, idleTimeout, jvmOpts, priority); } else { return null; } diff --git a/subprojects/launcher/src/integTest/groovy/org/gradle/launcher/daemon/DaemonPriorityIntegrationTest.groovy b/subprojects/launcher/src/integTest/groovy/org/gradle/launcher/daemon/DaemonPriorityIntegrationTest.groovy new file mode 100644 index 000000000000..db113da90add --- /dev/null +++ b/subprojects/launcher/src/integTest/groovy/org/gradle/launcher/daemon/DaemonPriorityIntegrationTest.groovy @@ -0,0 +1,65 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle.launcher.daemon + +import org.gradle.integtests.fixtures.daemon.DaemonIntegrationSpec +import org.gradle.internal.os.OperatingSystem + +class DaemonPriorityIntegrationTest extends DaemonIntegrationSpec { + + /* + * Our command line length is already close to the limit of what Windows can handle. + * The few extra arguments that the priority change requires seem to push it over the edge. + * Using a distribution drastically shrinks the command line length, as the classpath is only + * one jar in that case. + */ + def setup() { + if (OperatingSystem.current().isWindows()) { + requireGradleDistribution() + } + } + + def "forks new daemon when priority is set to a different value via command line"() { + when: + run("help") + + then: + daemons.daemons.size() == 1 + + when: + executer.withArguments("--priority", "low") + run("help") + + then: + daemons.daemons.size() == 2 + } + + def "forks new daemon when priority is set to a different value via properties"() { + when: + run("help") + + then: + daemons.daemons.size() == 1 + + when: + file("gradle.properties") << "org.gradle.priority=low" + run("help") + + then: + daemons.daemons.size() == 2 + } +} diff --git a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/bootstrap/DaemonMain.java b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/bootstrap/DaemonMain.java index b48ea48102bd..9331f085be4b 100644 --- a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/bootstrap/DaemonMain.java +++ b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/bootstrap/DaemonMain.java @@ -31,6 +31,7 @@ import org.gradle.internal.service.scopes.GradleUserHomeScopeServiceRegistry; import org.gradle.launcher.bootstrap.EntryPoint; import org.gradle.launcher.bootstrap.ExecutionListener; +import org.gradle.launcher.daemon.configuration.DaemonParameters; import org.gradle.launcher.daemon.configuration.DaemonServerConfiguration; import org.gradle.launcher.daemon.configuration.DefaultDaemonServerConfiguration; import org.gradle.launcher.daemon.context.DaemonContext; @@ -79,6 +80,7 @@ protected void doAction(String[] args, ExecutionListener listener) { int periodicCheckIntervalMs; boolean singleUse; String daemonUid; + DaemonParameters.Priority priority; List additionalClassPath; KryoBackedDecoder decoder = new KryoBackedDecoder(new EncodedStream.EncodedInput(System.in)); @@ -89,6 +91,7 @@ protected void doAction(String[] args, ExecutionListener listener) { periodicCheckIntervalMs = decoder.readSmallInt(); singleUse = decoder.readBoolean(); daemonUid = decoder.readString(); + priority = DaemonParameters.Priority.values()[decoder.readSmallInt()]; int argCount = decoder.readSmallInt(); startupOpts = new ArrayList(argCount); for (int i = 0; i < argCount; i++) { @@ -104,7 +107,7 @@ protected void doAction(String[] args, ExecutionListener listener) { } NativeServices.initialize(gradleHomeDir); - DaemonServerConfiguration parameters = new DefaultDaemonServerConfiguration(daemonUid, daemonBaseDir, idleTimeoutMs, periodicCheckIntervalMs, singleUse, startupOpts); + DaemonServerConfiguration parameters = new DefaultDaemonServerConfiguration(daemonUid, daemonBaseDir, idleTimeoutMs, periodicCheckIntervalMs, singleUse, priority, startupOpts); LoggingServiceRegistry loggingRegistry = LoggingServiceRegistry.newCommandLineProcessLogging(); LoggingManagerInternal loggingManager = loggingRegistry.newInstance(LoggingManagerInternal.class); diff --git a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/client/DefaultDaemonStarter.java b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/client/DefaultDaemonStarter.java index 74ce0fd2db1f..df93ab6ff085 100755 --- a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/client/DefaultDaemonStarter.java +++ b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/client/DefaultDaemonStarter.java @@ -27,6 +27,7 @@ import org.gradle.internal.installation.CurrentGradleInstallation; import org.gradle.internal.installation.GradleInstallation; import org.gradle.internal.io.StreamByteBuffer; +import org.gradle.internal.os.OperatingSystem; import org.gradle.internal.serialize.FlushableEncoder; import org.gradle.internal.serialize.kryo.KryoBackedEncoder; import org.gradle.internal.time.Time; @@ -48,6 +49,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.UUID; @@ -93,6 +95,7 @@ public DaemonStartupInfo startDaemon(boolean singleUse) { versionValidator.validate(daemonParameters); List daemonArgs = new ArrayList(); + daemonArgs.addAll(getPriorityArgs(daemonParameters.getPriority())); daemonArgs.add(daemonParameters.getEffectiveJvm().getJavaExecutable().getAbsolutePath()); List daemonOpts = daemonParameters.getEffectiveJvmArgs(); @@ -119,6 +122,7 @@ public DaemonStartupInfo startDaemon(boolean singleUse) { encoder.writeSmallInt(daemonParameters.getPeriodicCheckInterval()); encoder.writeBoolean(singleUse); encoder.writeString(daemonUid); + encoder.writeSmallInt(daemonParameters.getPriority().ordinal()); encoder.writeSmallInt(daemonOpts.size()); for (String daemonOpt : daemonOpts) { encoder.writeString(daemonOpt); @@ -136,6 +140,20 @@ public DaemonStartupInfo startDaemon(boolean singleUse) { return startProcess(daemonArgs, daemonDir.getVersionedDir(), stdInput); } + private List getPriorityArgs(DaemonParameters.Priority priority) { + if (priority == DaemonParameters.Priority.NORMAL) { + return Collections.emptyList(); + } + OperatingSystem os = OperatingSystem.current(); + if (os.isUnix()) { + return Arrays.asList("nice", "-n", "10"); + } else if (os.isWindows()) { + return Arrays.asList("cmd", "/C", "start", "\"Gradle build daemon\"", "/B", "/belownormal", "/WAIT"); + } else { + return Collections.emptyList(); + } + } + private DaemonStartupInfo startProcess(List args, File workingDir, InputStream stdInput) { LOGGER.debug("Starting daemon process: workingDir = {}, daemonArgs: {}", workingDir, args); Timer clock = Time.startTimer(); diff --git a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/DaemonBuildOptions.java b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/DaemonBuildOptions.java index d1670a32feae..10dc969433d5 100644 --- a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/DaemonBuildOptions.java +++ b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/DaemonBuildOptions.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Locale; public class DaemonBuildOptions { @@ -49,6 +50,7 @@ public class DaemonBuildOptions { options.add(new ForegroundOption()); options.add(new StopOption()); options.add(new StatusOption()); + options.add(new PriorityOption()); DaemonBuildOptions.options = Collections.unmodifiableList(options); } @@ -201,4 +203,21 @@ public void applyTo(DaemonParameters settings, Origin origin) { settings.setStatus(true); } } + + public static class PriorityOption extends StringBuildOption { + public static final String GRADLE_PROPERTY = "org.gradle.priority"; + + public PriorityOption() { + super(GRADLE_PROPERTY, CommandLineOptionConfiguration.create("priority", "Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Values are 'normal' (default) or 'low'").incubating()); + } + + @Override + public void applyTo(String value, DaemonParameters settings, Origin origin) { + try { + settings.setPriority(DaemonParameters.Priority.valueOf(value.toUpperCase(Locale.ROOT))); + } catch (IllegalArgumentException e) { + origin.handleInvalidValue(value); + } + } + } } diff --git a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/DaemonParameters.java b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/DaemonParameters.java index 86aeea145bb0..d6643bf37ee8 100644 --- a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/DaemonParameters.java +++ b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/DaemonParameters.java @@ -53,6 +53,7 @@ public class DaemonParameters { private boolean foreground; private boolean stop; private boolean status; + private Priority priority = Priority.NORMAL; private JavaInfo jvm = Jvm.current(); public DaemonParameters(BuildLayoutParameters layout) { @@ -207,4 +208,17 @@ public void setStatus(boolean status) { public Map getEnvironmentVariables() { return envVariables; } + + public Priority getPriority() { + return priority; + } + + public void setPriority(Priority priority) { + this.priority = priority; + } + + public enum Priority { + LOW, + NORMAL, + } } diff --git a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/DaemonServerConfiguration.java b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/DaemonServerConfiguration.java index d2602a62164f..c1466eff8fa0 100644 --- a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/DaemonServerConfiguration.java +++ b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/DaemonServerConfiguration.java @@ -31,5 +31,7 @@ public interface DaemonServerConfiguration { List getJvmOptions(); + DaemonParameters.Priority getPriority(); + boolean isSingleUse(); } diff --git a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/DefaultDaemonServerConfiguration.java b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/DefaultDaemonServerConfiguration.java index 5f7f7f1c7c69..3bd1fb58c6e2 100644 --- a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/DefaultDaemonServerConfiguration.java +++ b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/DefaultDaemonServerConfiguration.java @@ -26,14 +26,16 @@ public class DefaultDaemonServerConfiguration implements DaemonServerConfigurati private final int idleTimeoutMs; private final int periodicCheckIntervalMs; private final boolean singleUse; + private final DaemonParameters.Priority priority; private final List jvmOptions; - public DefaultDaemonServerConfiguration(String daemonUid, File daemonBaseDir, int idleTimeoutMs, int periodicCheckIntervalMs, boolean singleUse, List jvmOptions) { + public DefaultDaemonServerConfiguration(String daemonUid, File daemonBaseDir, int idleTimeoutMs, int periodicCheckIntervalMs, boolean singleUse, DaemonParameters.Priority priority, List jvmOptions) { this.daemonUid = daemonUid; this.daemonBaseDir = daemonBaseDir; this.idleTimeoutMs = idleTimeoutMs; this.periodicCheckIntervalMs = periodicCheckIntervalMs; this.singleUse = singleUse; + this.priority = priority; this.jvmOptions = jvmOptions; } @@ -57,6 +59,10 @@ public String getUid() { return daemonUid; } + public DaemonParameters.Priority getPriority() { + return priority; + } + @Override public List getJvmOptions() { return jvmOptions; diff --git a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/ForegroundDaemonConfiguration.java b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/ForegroundDaemonConfiguration.java index dd9bcdfa428b..ea5b237f8e37 100644 --- a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/ForegroundDaemonConfiguration.java +++ b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/ForegroundDaemonConfiguration.java @@ -23,6 +23,6 @@ public class ForegroundDaemonConfiguration extends DefaultDaemonServerConfiguration { public ForegroundDaemonConfiguration(String daemonUid, File daemonBaseDir, int idleTimeoutMs, int periodicCheckIntervalMs) { // Foreground daemon cannot be 'told' what's his startup options as the client sits in the same process so we will infer the jvm opts from the inputArguments() - super(daemonUid, daemonBaseDir, idleTimeoutMs, periodicCheckIntervalMs, false, new CurrentProcess().getJvmOptions().getAllImmutableJvmArgs()); + super(daemonUid, daemonBaseDir, idleTimeoutMs, periodicCheckIntervalMs, false, DaemonParameters.Priority.NORMAL, new CurrentProcess().getJvmOptions().getAllImmutableJvmArgs()); } } diff --git a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/context/DaemonCompatibilitySpec.java b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/context/DaemonCompatibilitySpec.java index eaad446e4956..c6ced1ceab7a 100644 --- a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/context/DaemonCompatibilitySpec.java +++ b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/context/DaemonCompatibilitySpec.java @@ -36,26 +36,32 @@ public String whyUnsatisfied(DaemonContext context) { return "Java home is different.\n" + description(context); } else if (!daemonOptsMatch(context)) { return "At least one daemon option is different.\n" + description(context); + } else if (!priorityMatches(context)) { + return "Process priority is different.\n" + description(context); } return null; } private String description(DaemonContext context) { return "Wanted: " + this + "\n" - + "Actual: " + context + "\n"; + + "Actual: " + context + "\n"; } private boolean daemonOptsMatch(DaemonContext potentialContext) { return potentialContext.getDaemonOpts().containsAll(desiredContext.getDaemonOpts()) - && potentialContext.getDaemonOpts().size() == desiredContext.getDaemonOpts().size(); + && potentialContext.getDaemonOpts().size() == desiredContext.getDaemonOpts().size(); } private boolean javaHomeMatches(DaemonContext potentialContext) { return canonicalize(potentialContext.getJavaHome()).equals(canonicalize(desiredContext.getJavaHome())); } + private boolean priorityMatches(DaemonContext context) { + return desiredContext.getPriority() == context.getPriority(); + } + @Override public String toString() { return desiredContext.toString(); } -} \ No newline at end of file +} diff --git a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/context/DaemonContext.java b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/context/DaemonContext.java index 3c2aba590b68..5d353dbe243a 100644 --- a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/context/DaemonContext.java +++ b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/context/DaemonContext.java @@ -15,6 +15,8 @@ */ package org.gradle.launcher.daemon.context; +import org.gradle.launcher.daemon.configuration.DaemonParameters; + import java.io.File; import java.io.Serializable; import java.util.List; @@ -65,4 +67,6 @@ public interface DaemonContext extends Serializable { * @return the JVM options that the daemon was started with */ List getDaemonOpts(); -} \ No newline at end of file + + DaemonParameters.Priority getPriority(); +} diff --git a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/context/DaemonContextBuilder.java b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/context/DaemonContextBuilder.java index e5e8ceeaf399..efb6e2f4d58a 100644 --- a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/context/DaemonContextBuilder.java +++ b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/context/DaemonContextBuilder.java @@ -42,6 +42,7 @@ public class DaemonContextBuilder implements Factory { private Integer idleTimeout; private Locale locale = Locale.getDefault(); private List daemonOpts = Lists.newArrayList(); + private DaemonParameters.Priority priority; public DaemonContextBuilder(ProcessEnvironment processEnvironment) { javaHome = canonicalize(Jvm.current().getJavaHome()); @@ -104,9 +105,14 @@ public void setDaemonOpts(List daemonOpts) { this.daemonOpts = daemonOpts; } + public void setPriority(DaemonParameters.Priority priority) { + this.priority = priority; + } + public void useDaemonParameters(DaemonParameters daemonParameters) { setJavaHome(daemonParameters.getEffectiveJvm().getJavaHome()); setDaemonOpts(daemonParameters.getEffectiveJvmArgs()); + setPriority(daemonParameters.getPriority()); } /** @@ -116,6 +122,6 @@ public DaemonContext create() { if (daemonRegistryDir == null) { throw new IllegalStateException("Registry dir must be specified."); } - return new DefaultDaemonContext(uid, javaHome, daemonRegistryDir, pid, idleTimeout, daemonOpts); + return new DefaultDaemonContext(uid, javaHome, daemonRegistryDir, pid, idleTimeout, daemonOpts, priority); } -} \ No newline at end of file +} diff --git a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/context/DefaultDaemonContext.java b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/context/DefaultDaemonContext.java index 7a97a2c0baeb..d083c9b4bf87 100644 --- a/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/context/DefaultDaemonContext.java +++ b/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/context/DefaultDaemonContext.java @@ -18,6 +18,7 @@ import com.google.common.base.Joiner; import org.gradle.internal.serialize.Decoder; import org.gradle.internal.serialize.Encoder; +import org.gradle.launcher.daemon.configuration.DaemonParameters; import java.io.File; import java.util.ArrayList; @@ -38,19 +39,21 @@ public class DefaultDaemonContext implements DaemonContext { private final Long pid; private final Integer idleTimeout; private final List daemonOpts; + private final DaemonParameters.Priority priority; - public DefaultDaemonContext(String uid, File javaHome, File daemonRegistryDir, Long pid, Integer idleTimeout, List daemonOpts) { + public DefaultDaemonContext(String uid, File javaHome, File daemonRegistryDir, Long pid, Integer idleTimeout, List daemonOpts, DaemonParameters.Priority priority) { this.uid = uid; this.javaHome = javaHome; this.daemonRegistryDir = daemonRegistryDir; this.pid = pid; this.idleTimeout = idleTimeout; this.daemonOpts = daemonOpts; + this.priority = priority; } public String toString() { - return String.format("DefaultDaemonContext[uid=%s,javaHome=%s,daemonRegistryDir=%s,pid=%s,idleTimeout=%s,daemonOpts=%s]", - uid, javaHome, daemonRegistryDir, pid, idleTimeout, Joiner.on(',').join(daemonOpts)); + return String.format("DefaultDaemonContext[uid=%s,javaHome=%s,daemonRegistryDir=%s,pid=%s,idleTimeout=%s,priority=%s,daemonOpts=%s]", + uid, javaHome, daemonRegistryDir, pid, idleTimeout, priority, Joiner.on(',').join(daemonOpts)); } public String getUid() { @@ -77,6 +80,11 @@ public List getDaemonOpts() { return daemonOpts; } + @Override + public DaemonParameters.Priority getPriority() { + return priority; + } + private static class Serializer implements org.gradle.internal.serialize.Serializer { @Override @@ -89,10 +97,11 @@ public DefaultDaemonContext read(Decoder decoder) throws Exception { Integer idle = decoder.readBoolean() ? decoder.readInt() : null; int daemonOptCount = decoder.readInt(); List daemonOpts = new ArrayList(daemonOptCount); - for (int i=0; i concurrent.start { - def context = new DefaultDaemonContext("$idx", new File("$idx"), new File("$idx"), idx, 5000, []) + def context = new DefaultDaemonContext("$idx", new File("$idx"), new File("$idx"), idx, 5000, [], DaemonParameters.Priority.NORMAL) registry.store(new DaemonInfo( new SocketInetAddress(new Inet6Address(), 8888 + idx), context, "foo-$idx".bytes, Idle)) } diff --git a/subprojects/launcher/src/test/groovy/org/gradle/launcher/daemon/server/DaemonRegistryUnavailableExpirationStrategyTest.groovy b/subprojects/launcher/src/test/groovy/org/gradle/launcher/daemon/server/DaemonRegistryUnavailableExpirationStrategyTest.groovy index adf9dcd4f30c..d08d0b253814 100644 --- a/subprojects/launcher/src/test/groovy/org/gradle/launcher/daemon/server/DaemonRegistryUnavailableExpirationStrategyTest.groovy +++ b/subprojects/launcher/src/test/groovy/org/gradle/launcher/daemon/server/DaemonRegistryUnavailableExpirationStrategyTest.groovy @@ -16,6 +16,7 @@ package org.gradle.launcher.daemon.server import org.gradle.internal.remote.Address +import org.gradle.launcher.daemon.configuration.DaemonParameters import org.gradle.launcher.daemon.context.DaemonContext import org.gradle.launcher.daemon.context.DefaultDaemonContext import org.gradle.launcher.daemon.registry.DaemonDir @@ -41,7 +42,7 @@ class DaemonRegistryUnavailableExpirationStrategyTest extends Specification { def "daemon should expire when registry file is unreachable"() { given: DaemonRegistryUnavailableExpirationStrategy expirationStrategy = new DaemonRegistryUnavailableExpirationStrategy(daemon) - DaemonContext daemonContext = new DefaultDaemonContext("user", null, tempDir.file("BOGUS"), 51234L, 10000, [] as List) + DaemonContext daemonContext = new DefaultDaemonContext("user", null, tempDir.file("BOGUS"), 51234L, 10000, [] as List, DaemonParameters.Priority.NORMAL) when: 1 * daemon.getDaemonContext() >> { daemonContext } @@ -59,7 +60,7 @@ class DaemonRegistryUnavailableExpirationStrategyTest extends Specification { return "DAEMON_ADDRESS" } } - DaemonContext daemonContext = new DefaultDaemonContext("user", null, daemonDir, 51234L, 10000, [] as List) + DaemonContext daemonContext = new DefaultDaemonContext("user", null, daemonDir, 51234L, 10000, [] as List, DaemonParameters.Priority.NORMAL) DaemonDir daemonDir = new DaemonDir(daemonDir) DaemonRegistry registry = new EmbeddedDaemonRegistry() daemonDir.getRegistry().createNewFile() diff --git a/subprojects/launcher/src/test/groovy/org/gradle/launcher/daemon/server/DaemonServicesTest.groovy b/subprojects/launcher/src/test/groovy/org/gradle/launcher/daemon/server/DaemonServicesTest.groovy index 83a9984a4364..7974bb2c2dc6 100644 --- a/subprojects/launcher/src/test/groovy/org/gradle/launcher/daemon/server/DaemonServicesTest.groovy +++ b/subprojects/launcher/src/test/groovy/org/gradle/launcher/daemon/server/DaemonServicesTest.groovy @@ -19,6 +19,7 @@ import org.gradle.internal.classpath.ClassPath import org.gradle.internal.logging.LoggingManagerInternal import org.gradle.internal.logging.services.LoggingServiceRegistry import org.gradle.internal.nativeintegration.ProcessEnvironment +import org.gradle.launcher.daemon.configuration.DaemonParameters import org.gradle.launcher.daemon.configuration.DefaultDaemonServerConfiguration import org.gradle.launcher.daemon.registry.DaemonDir import org.gradle.launcher.daemon.server.scaninfo.DaemonScanInfo @@ -34,10 +35,10 @@ class DaemonServicesTest extends Specification { @Rule TestNameTestDirectoryProvider tmp = new TestNameTestDirectoryProvider() - final DaemonServices services = new DaemonServices(new DefaultDaemonServerConfiguration("uid", tmp.testDirectory, 100, 50, false, asList()), + final DaemonServices services = new DaemonServices(new DefaultDaemonServerConfiguration("uid", tmp.testDirectory, 100, 50, false, DaemonParameters.Priority.NORMAL, asList()), LoggingServiceRegistry.newEmbeddableLogging(), Mock(LoggingManagerInternal), Stub(ClassPath)) - final DaemonServices singleRunServices = new DaemonServices(new DefaultDaemonServerConfiguration("uid", tmp.testDirectory, 200, 50, true, asList()), + final DaemonServices singleRunServices = new DaemonServices(new DefaultDaemonServerConfiguration("uid", tmp.testDirectory, 200, 50, true, DaemonParameters.Priority.NORMAL, asList()), LoggingServiceRegistry.newEmbeddableLogging(), Mock(LoggingManagerInternal), Stub(ClassPath))