Add WorkerKey to the ResourceSet.
This field will be used in next cls in functions `areResourcesAvailable` and `acquire` from `ResourceManager`. This is the part of worker-as-resource plan.
PiperOrigin-RevId: 448934201
diff --git a/src/main/java/com/google/devtools/build/lib/actions/BUILD b/src/main/java/com/google/devtools/build/lib/actions/BUILD
index 0fe4c4f..042a9e35 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/actions/BUILD
@@ -305,9 +305,11 @@
"//src/main/java/com/google/devtools/build/lib/unix",
"//src/main/java/com/google/devtools/build/lib/unix:procmeminfo_parser",
"//src/main/java/com/google/devtools/build/lib/util:os",
+ "//src/main/java/com/google/devtools/build/lib/worker:worker_key",
"//src/main/java/com/google/devtools/common/options",
"//third_party:flogger",
"//third_party:guava",
+ "//third_party:jsr305",
],
)
@@ -369,5 +371,6 @@
"//src/main/java/com/google/devtools/build/lib/util:os",
"//src/main/java/com/google/devtools/build/lib/worker",
"//third_party:guava",
+ "//third_party:jsr305",
],
)
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ResourceManager.java b/src/main/java/com/google/devtools/build/lib/actions/ResourceManager.java
index 145fd8c..7674bff 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/ResourceManager.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/ResourceManager.java
@@ -25,13 +25,13 @@
import com.google.devtools.build.lib.util.OS;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.worker.Worker;
-import com.google.devtools.build.lib.worker.WorkerKey;
import com.google.devtools.build.lib.worker.WorkerPool;
import java.io.IOException;
import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.concurrent.CountDownLatch;
+import javax.annotation.Nullable;
/**
* Used to keep track of resources consumed by the Blaze action execution threads and throttle them
@@ -69,39 +69,28 @@
* ResourcePriority)} that must be closed in order to free the resources again.
*/
public static class ResourceHandle implements AutoCloseable {
- final ResourceManager rm;
- final ActionExecutionMetadata actionMetadata;
- final ResourceSet resourceSet;
+ private final ResourceManager rm;
+ private final ActionExecutionMetadata actionMetadata;
+ private final ResourceSet resourceSet;
+ private final Worker worker;
- public ResourceHandle(ResourceManager rm, ActionExecutionMetadata actionMetadata,
- ResourceSet resources) {
+ private ResourceHandle(
+ ResourceManager rm,
+ ActionExecutionMetadata actionMetadata,
+ ResourceSet resources,
+ Worker worker) {
this.rm = rm;
this.actionMetadata = actionMetadata;
this.resourceSet = resources;
- }
-
- /**
- * Closing the ResourceHandle releases the resources associated with it.
- */
- @Override
- public void close() {
- rm.releaseResources(actionMetadata, resourceSet);
- }
- }
-
- /**
- * A handle returned by {@link #acquireWorkerResources(ActionExecutionMetadata, ResourceSet,
- * WorkerKey, ResourcePriority)} that must be closed in order to free the resources again.
- */
- public static class ResourceHandleWithWorker implements AutoCloseable {
- final ResourceHandle resourceHandle;
- final Worker worker;
-
- public ResourceHandleWithWorker(ResourceHandle resourceHandle, Worker worker) {
- this.resourceHandle = resourceHandle;
this.worker = worker;
}
+ private ResourceHandle(
+ ResourceManager rm, ActionExecutionMetadata actionMetadata, ResourceSet resources) {
+ this(rm, actionMetadata, resources, /* worker= */ null);
+ }
+
+ @Nullable
public Worker getWorker() {
return worker;
}
@@ -109,16 +98,17 @@
/** Closing the ResourceHandle releases the resources associated with it. */
@Override
public void close() {
- this.resourceHandle.close();
+ rm.releaseResources(actionMetadata, resourceSet);
}
}
- private final ThreadLocal<Boolean> threadLocked = new ThreadLocal<Boolean>() {
- @Override
- protected Boolean initialValue() {
- return false;
- }
- };
+ private final ThreadLocal<Boolean> threadLocked =
+ new ThreadLocal<Boolean>() {
+ @Override
+ protected Boolean initialValue() {
+ return false;
+ }
+ };
/**
* Defines the possible priorities of resources. The earlier elements in this enum will get first
@@ -135,9 +125,7 @@
static ResourceManager instance = new ResourceManager();
}
- /**
- * Returns singleton instance of the resource manager.
- */
+ /** Returns singleton instance of the resource manager. */
public static ResourceManager instance() {
return Singleton.instance;
}
@@ -192,16 +180,17 @@
/** If set, local-only actions are given priority over dynamically run actions. */
private boolean prioritizeLocalActions;
- private ResourceManager() {
- }
+ private ResourceManager() {}
- @VisibleForTesting public static ResourceManager instanceForTestingOnly() {
+ @VisibleForTesting
+ public static ResourceManager instanceForTestingOnly() {
return new ResourceManager();
}
/**
* Resets resource manager state and releases all thread locks.
- * Note - it does not reset available resources. Use separate call to setAvailableResources().
+ *
+ * <p>Note - it does not reset available resources. Use separate call to setAvailableResources().
*/
public synchronized void resetResourceUsage() {
usedCpu = 0;
@@ -222,8 +211,9 @@
}
/**
- * Sets available resources using given resource set. Must be called
- * at least once before using resource manager.
+ * Sets available resources using given resource set.
+ *
+ * <p>Must be called at least once before using resource manager.
*/
public synchronized void setAvailableResources(ResourceSet resources) {
Preconditions.checkNotNull(resources);
@@ -257,32 +247,22 @@
}
/**
- * Acuqires requested resource set and worker. Will block if resource is not available. The worker
- * isn't released as part of the AutoCloseable.
- */
- public ResourceHandleWithWorker acquireWorkerResources(
- ActionExecutionMetadata owner,
- ResourceSet resources,
- WorkerKey workerKey,
- ResourcePriority priority)
- throws InterruptedException, IOException {
- Worker worker = this.workerPool.borrowObject(workerKey);
- ResourceHandle handle = acquireResources(owner, resources, priority);
- return new ResourceHandleWithWorker(handle, worker);
- }
-
- /**
* Acquires requested resource set. Will block if resource is not available. NB! This method must
* be thread-safe!
*/
public ResourceHandle acquireResources(
ActionExecutionMetadata owner, ResourceSet resources, ResourcePriority priority)
- throws InterruptedException {
+ throws InterruptedException, IOException {
Preconditions.checkNotNull(
resources, "acquireResources called with resources == NULL during %s", owner);
Preconditions.checkState(
!threadHasResources(), "acquireResources with existing resource lock during %s", owner);
+ Worker worker = null;
+ if (resources.getWorkerKey() != null) {
+ worker = this.workerPool.borrowObject(resources.getWorkerKey());
+ }
+
AutoProfiler p =
profiled("Acquiring resources for: " + owner.describe(), ProfilerTask.ACTION_LOCK);
CountDownLatch latch = null;
@@ -313,7 +293,7 @@
p.complete();
}
- return new ResourceHandle(this, owner, resources);
+ return new ResourceHandle(this, owner, resources, worker);
}
/**
@@ -499,7 +479,7 @@
if (localMemoryEstimate && OS.getCurrent() == OS.LINUX) {
try {
ProcMeminfoParser memInfo = new ProcMeminfoParser();
- double totalFreeRam = memInfo.getFreeRamKb() / 1024;
+ double totalFreeRam = memInfo.getFreeRamKb() / 1024.0;
double reserveMemory = staticResources.getMemoryMb();
remainingRam = totalFreeRam - reserveMemory;
} catch (IOException e) {
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ResourceSet.java b/src/main/java/com/google/devtools/build/lib/actions/ResourceSet.java
index 053a810..7bdfa2d 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/ResourceSet.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/ResourceSet.java
@@ -18,10 +18,12 @@
import com.google.common.primitives.Doubles;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.util.OS;
+import com.google.devtools.build.lib.worker.WorkerKey;
import com.google.devtools.common.options.Converter;
import com.google.devtools.common.options.OptionsParsingException;
import java.util.Iterator;
import java.util.NoSuchElementException;
+import javax.annotation.Nullable;
/**
* Instances of this class represent an estimate of the resource consumption for a particular
@@ -44,10 +46,19 @@
/** The number of local tests. */
private final int localTestCount;
- private ResourceSet(double memoryMb, double cpuUsage, int localTestCount) {
+ /** The workerKey of used worker. Null if no worker is used. */
+ @Nullable private final WorkerKey workerKey;
+
+ private ResourceSet(
+ double memoryMb, double cpuUsage, int localTestCount, @Nullable WorkerKey workerKey) {
this.memoryMb = memoryMb;
this.cpuUsage = cpuUsage;
this.localTestCount = localTestCount;
+ this.workerKey = workerKey;
+ }
+
+ private ResourceSet(double memoryMb, double cpuUsage, int localTestCount) {
+ this(memoryMb, cpuUsage, localTestCount, /* workerKey= */ null);
}
/**
@@ -78,10 +89,15 @@
* represent available resources.
*/
public static ResourceSet create(double memoryMb, double cpuUsage, int localTestCount) {
- if (memoryMb == 0 && cpuUsage == 0 && localTestCount == 0) {
+ return createWithWorkerKey(memoryMb, cpuUsage, localTestCount, /* workerKey= */ null);
+ }
+
+ public static ResourceSet createWithWorkerKey(
+ double memoryMb, double cpuUsage, int localTestCount, WorkerKey workerKey) {
+ if (memoryMb == 0 && cpuUsage == 0 && localTestCount == 0 && workerKey == null) {
return ZERO;
}
- return new ResourceSet(memoryMb, cpuUsage, localTestCount);
+ return new ResourceSet(memoryMb, cpuUsage, localTestCount, workerKey);
}
/** Returns the amount of real memory (resident set size) used in MB. */
@@ -90,6 +106,15 @@
}
/**
+ * Returns the workerKey of worker.
+ *
+ * <p>If there is no worker requested, then returns null
+ */
+ public WorkerKey getWorkerKey() {
+ return workerKey;
+ }
+
+ /**
* Returns the number of CPUs (or fractions thereof) used. For a CPU-bound single-threaded
* process, this will be 1.0. For a single-threaded process which spends part of its time waiting
* for I/O, this will be somewhere between 0.0 and 1.0. For a multi-threaded or multi-process
diff --git a/src/main/java/com/google/devtools/build/lib/worker/BUILD b/src/main/java/com/google/devtools/build/lib/worker/BUILD
index b312e76..ab395d4 100644
--- a/src/main/java/com/google/devtools/build/lib/worker/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/worker/BUILD
@@ -18,20 +18,16 @@
"WorkerModule.java",
"WorkerParser.java",
"WorkerSpawnStrategy.java",
+ "WorkerKey.java",
],
),
deps = [
- # ":worker_spawn_runner",
- "//third_party:guava",
- "//third_party/protobuf:protobuf_java",
- "//third_party/protobuf:protobuf_java_util",
+ ":worker_key",
"//src/main/java/com/google/devtools/build/lib/actions",
- "//src/main/java/com/google/devtools/build/lib/actions:execution_requirements",
"//src/main/java/com/google/devtools/build/lib/buildeventstream/proto:build_event_stream_java_proto",
"//src/main/java/com/google/devtools/build/lib/events",
"//src/main/java/com/google/devtools/build/lib/sandbox:sandbox_helpers",
"//src/main/java/com/google/devtools/build/lib/shell",
- "//src/main/java/com/google/devtools/build/lib/util:command",
"//src/main/java/com/google/devtools/build/lib/util:resource_converter",
"//src/main/java/com/google/devtools/build/lib/vfs",
"//src/main/java/com/google/devtools/build/lib/vfs:pathfragment",
@@ -42,7 +38,10 @@
"//third_party:auto_value",
"//third_party:flogger",
"//third_party:gson",
+ "//third_party:guava",
"//third_party:jsr305",
+ "//third_party/protobuf:protobuf_java",
+ "//third_party/protobuf:protobuf_java_util",
],
)
@@ -69,11 +68,13 @@
deps = [
":worker",
":worker_files_hash",
+ ":worker_key",
"//src/main/java/com/google/devtools/build/lib:runtime",
"//src/main/java/com/google/devtools/build/lib/actions",
"//src/main/java/com/google/devtools/build/lib/actions:action_input_helper",
"//src/main/java/com/google/devtools/build/lib/actions:artifacts",
"//src/main/java/com/google/devtools/build/lib/actions:execution_requirements",
+ "//src/main/java/com/google/devtools/build/lib/actions:localhost_capacity",
"//src/main/java/com/google/devtools/build/lib/actions:resource_manager",
"//src/main/java/com/google/devtools/build/lib/events",
"//src/main/java/com/google/devtools/build/lib/exec:bin_tools",
@@ -134,3 +135,17 @@
"//third_party/protobuf:protobuf_java_util",
],
)
+
+java_library(
+ name = "worker_key",
+ srcs = [
+ "WorkerKey.java",
+ ],
+ deps = [
+ "//src/main/java/com/google/devtools/build/lib/actions:execution_requirements",
+ "//src/main/java/com/google/devtools/build/lib/util:command",
+ "//src/main/java/com/google/devtools/build/lib/vfs",
+ "//src/main/java/com/google/devtools/build/lib/vfs:pathfragment",
+ "//third_party:guava",
+ ],
+)
diff --git a/src/main/java/com/google/devtools/build/lib/worker/WorkerFactory.java b/src/main/java/com/google/devtools/build/lib/worker/WorkerFactory.java
index 81ef251..487e0a3 100644
--- a/src/main/java/com/google/devtools/build/lib/worker/WorkerFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/worker/WorkerFactory.java
@@ -31,7 +31,7 @@
import org.apache.commons.pool2.impl.DefaultPooledObject;
/** Factory used by the pool to create / destroy / validate worker processes. */
-class WorkerFactory extends BaseKeyedPooledObjectFactory<WorkerKey, Worker> {
+public class WorkerFactory extends BaseKeyedPooledObjectFactory<WorkerKey, Worker> {
// It's fine to use an AtomicInteger here (which is 32-bit), because it is only incremented when
// spawning a new worker, thus even under worst-case circumstances and buggy workers quitting
diff --git a/src/main/java/com/google/devtools/build/lib/worker/WorkerKey.java b/src/main/java/com/google/devtools/build/lib/worker/WorkerKey.java
index 6d55a54..2ffacc9 100644
--- a/src/main/java/com/google/devtools/build/lib/worker/WorkerKey.java
+++ b/src/main/java/com/google/devtools/build/lib/worker/WorkerKey.java
@@ -64,7 +64,7 @@
/** The format of the worker protocol sent to and read from the worker. */
private final WorkerProtocolFormat protocolFormat;
- WorkerKey(
+ public WorkerKey(
ImmutableList<String> args,
ImmutableMap<String, String> env,
Path execRoot,
diff --git a/src/main/java/com/google/devtools/build/lib/worker/WorkerPool.java b/src/main/java/com/google/devtools/build/lib/worker/WorkerPool.java
index c8d0b83..eda05ac 100644
--- a/src/main/java/com/google/devtools/build/lib/worker/WorkerPool.java
+++ b/src/main/java/com/google/devtools/build/lib/worker/WorkerPool.java
@@ -200,13 +200,17 @@
multiplexPools.values().forEach(GenericKeyedObjectPool::close);
}
- static class WorkerPoolConfig {
+ /**
+ * Describes the configuration of worker pool, e.g. number of maximal instances and priority of
+ * the workers.
+ */
+ public static class WorkerPoolConfig {
private final WorkerFactory workerFactory;
private final List<Entry<String, Integer>> workerMaxInstances;
private final List<Entry<String, Integer>> workerMaxMultiplexInstances;
private final List<String> highPriorityWorkers;
- WorkerPoolConfig(
+ public WorkerPoolConfig(
WorkerFactory workerFactory,
List<Entry<String, Integer>> workerMaxInstances,
List<Entry<String, Integer>> workerMaxMultiplexInstances,
diff --git a/src/main/java/com/google/devtools/build/lib/worker/WorkerSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/worker/WorkerSpawnRunner.java
index a7e0015..3fc169f 100644
--- a/src/main/java/com/google/devtools/build/lib/worker/WorkerSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/worker/WorkerSpawnRunner.java
@@ -33,8 +33,8 @@
import com.google.devtools.build.lib.actions.MetadataProvider;
import com.google.devtools.build.lib.actions.ResourceManager;
import com.google.devtools.build.lib.actions.ResourceManager.ResourceHandle;
-import com.google.devtools.build.lib.actions.ResourceManager.ResourceHandleWithWorker;
import com.google.devtools.build.lib.actions.ResourceManager.ResourcePriority;
+import com.google.devtools.build.lib.actions.ResourceSet;
import com.google.devtools.build.lib.actions.Spawn;
import com.google.devtools.build.lib.actions.SpawnMetrics;
import com.google.devtools.build.lib.actions.SpawnResult;
@@ -387,12 +387,18 @@
Stopwatch queueStopwatch = Stopwatch.createStarted();
if (workerOptions.workerAsResource) {
+ ResourceSet resourceSet =
+ ResourceSet.createWithWorkerKey(
+ spawn.getLocalResources().getMemoryMb(),
+ spawn.getLocalResources().getCpuUsage(),
+ spawn.getLocalResources().getLocalTestCount(),
+ key);
+
// Worker doesn't automatically return to pool after closing of the handle.
- try (ResourceHandleWithWorker handle =
- resourceManager.acquireWorkerResources(
+ try (ResourceHandle handle =
+ resourceManager.acquireResources(
owner,
- spawn.getLocalResources(),
- key,
+ resourceSet,
context.speculating() ? ResourcePriority.DYNAMIC_WORKER : ResourcePriority.LOCAL)) {
workerOwner.setWorker(handle.getWorker());
workerOwner.getWorker().setReporter(workerOptions.workerVerbose ? reporter : null);
@@ -430,6 +436,12 @@
response =
executeRequest(
spawn, context, inputFiles, outputs, workerOwner, key, request, spawnMetrics);
+ } catch (IOException e) {
+ restoreInterrupt(e);
+ String message =
+ "The IOException is thrown from worker allocation, but"
+ + " there is no worker allocation here.";
+ throw createUserExecException(e, message, Code.BORROW_FAILURE);
}
}
diff --git a/src/test/java/com/google/devtools/build/lib/actions/BUILD b/src/test/java/com/google/devtools/build/lib/actions/BUILD
index bbb6374..0cabee7 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/actions/BUILD
@@ -36,6 +36,7 @@
"//src/main/java/com/google/devtools/build/lib/actions:artifact_owner",
"//src/main/java/com/google/devtools/build/lib/actions:artifacts",
"//src/main/java/com/google/devtools/build/lib/actions:commandline_item",
+ "//src/main/java/com/google/devtools/build/lib/actions:execution_requirements",
"//src/main/java/com/google/devtools/build/lib/actions:file_metadata",
"//src/main/java/com/google/devtools/build/lib/actions:fileset_output_symlink",
"//src/main/java/com/google/devtools/build/lib/actions:localhost_capacity",
@@ -67,6 +68,8 @@
"//src/main/java/com/google/devtools/build/lib/vfs",
"//src/main/java/com/google/devtools/build/lib/vfs:pathfragment",
"//src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs",
+ "//src/main/java/com/google/devtools/build/lib/worker",
+ "//src/main/java/com/google/devtools/build/lib/worker:worker_key",
"//src/main/java/com/google/devtools/build/skyframe:skyframe-objects",
"//src/main/java/com/google/devtools/common/options",
"//src/main/java/net/starlark/java/eval",
@@ -79,6 +82,7 @@
"//src/test/java/com/google/devtools/build/lib/testutil:TestThread",
"//src/test/java/com/google/devtools/build/lib/testutil:TestUtils",
"//src/test/java/com/google/devtools/build/lib/vfs/util",
+ "//third_party:apache_commons_pool2",
"//third_party:auto_value",
"//third_party:guava",
"//third_party:guava-testlib",
diff --git a/src/test/java/com/google/devtools/build/lib/actions/ResourceManagerTest.java b/src/test/java/com/google/devtools/build/lib/actions/ResourceManagerTest.java
index 0de6d7e..0dee9f2 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/ResourceManagerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/ResourceManagerTest.java
@@ -16,8 +16,12 @@
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSortedMap;
+import com.google.common.hash.HashCode;
+import com.google.devtools.build.lib.actions.ExecutionRequirements.WorkerProtocolFormat;
import com.google.devtools.build.lib.actions.ResourceManager.ResourceHandle;
import com.google.devtools.build.lib.actions.ResourceManager.ResourcePriority;
import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
@@ -26,28 +30,40 @@
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.testutil.TestThread;
import com.google.devtools.build.lib.testutil.TestUtils;
+import com.google.devtools.build.lib.vfs.DigestHashFunction;
+import com.google.devtools.build.lib.vfs.FileSystem;
+import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
+import com.google.devtools.build.lib.worker.Worker;
+import com.google.devtools.build.lib.worker.WorkerFactory;
+import com.google.devtools.build.lib.worker.WorkerKey;
+import com.google.devtools.build.lib.worker.WorkerPool;
+import java.io.IOException;
import java.util.Collection;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nullable;
+import org.apache.commons.pool2.PooledObject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import org.mockito.Mock;
/** Tests for {@link ResourceManager}. */
@RunWith(JUnit4.class)
-public class ResourceManagerTest {
+public final class ResourceManagerTest {
+ private final FileSystem fs = new InMemoryFileSystem(DigestHashFunction.SHA256);
private final ActionExecutionMetadata resourceOwner = new ResourceOwnerStub();
private final ResourceManager rm = ResourceManager.instanceForTestingOnly();
+ @Mock private Worker worker;
private AtomicInteger counter;
CyclicBarrier sync;
CyclicBarrier sync2;
@Before
- public final void configureResourceManager() throws Exception {
+ public void configureResourceManager() throws Exception {
rm.setAvailableResources(
ResourceSet.create(/*memoryMb=*/ 1000, /*cpuUsage=*/ 1, /* localTestCount= */ 2));
counter = new AtomicInteger(0);
@@ -55,18 +71,47 @@
sync2 = new CyclicBarrier(2);
rm.resetResourceUsage();
rm.setPrioritizeLocalActions(true);
+ rm.setWorkerPool(createWorkerPool());
+ }
+
+ private WorkerPool createWorkerPool() {
+ return new WorkerPool(
+ new WorkerPool.WorkerPoolConfig(
+ new WorkerFactory(fs.getPath("/workerBase")) {
+ @Override
+ public Worker create(WorkerKey key) {
+ return worker;
+ }
+
+ @Override
+ public boolean validateObject(WorkerKey key, PooledObject<Worker> p) {
+ return true;
+ }
+ },
+ ImmutableList.of(),
+ ImmutableList.of(),
+ ImmutableList.of()));
}
private ResourceHandle acquire(double ram, double cpu, int tests, ResourcePriority priority)
- throws InterruptedException {
+ throws InterruptedException, IOException {
return rm.acquireResources(resourceOwner, ResourceSet.create(ram, cpu, tests), priority);
}
private ResourceHandle acquire(double ram, double cpu, int tests)
- throws InterruptedException {
+ throws InterruptedException, IOException {
return acquire(ram, cpu, tests, ResourcePriority.LOCAL);
}
+ private ResourceHandle acquire(double ram, double cpu, int tests, String mnemonic)
+ throws InterruptedException, IOException {
+
+ return rm.acquireResources(
+ resourceOwner,
+ ResourceSet.createWithWorkerKey(ram, cpu, tests, createWorkerKey(mnemonic)),
+ ResourcePriority.LOCAL);
+ }
+
private ResourceHandle acquireNonblocking(double ram, double cpu, int tests) {
return rm.tryAcquire(resourceOwner, ResourceSet.create(ram, cpu, tests));
}
@@ -79,6 +124,20 @@
assertThat(counter.incrementAndGet()).isEqualTo(count);
}
+ private WorkerKey createWorkerKey(String mnemonic) {
+ return new WorkerKey(
+ /* args= */ ImmutableList.of(),
+ /* env= */ ImmutableMap.of(),
+ /* execRoot= */ fs.getPath("/outputbase/execroot/workspace"),
+ /* mnemonic= */ mnemonic,
+ /* workerFilesCombinedHash= */ HashCode.fromInt(0),
+ /* workerFilesWithDigests= */ ImmutableSortedMap.of(),
+ /* sandboxed= */ false,
+ /* multiplex= */ false,
+ /* cancellable= */ false,
+ WorkerProtocolFormat.PROTO);
+ }
+
@Test
public void testOverBudgetRequests() throws Exception {
assertThat(rm.inUse()).isFalse();
@@ -607,6 +666,19 @@
return sync;
}
+ @Test
+ public void testAcquireWithWorker_acquireAndRelease() throws Exception {
+ int memory = 100;
+
+ assertThat(rm.inUse()).isFalse();
+ acquire(memory, 1, 0, "dummy");
+ assertThat(rm.inUse()).isTrue();
+ release(memory, 1, 0);
+ // When that RAM is released,
+ // Then Resource Manager will not be "in use":
+ assertThat(rm.inUse()).isFalse();
+ }
+
private static class ResourceOwnerStub implements ActionExecutionMetadata {
@Override
diff --git a/src/test/java/com/google/devtools/build/lib/worker/BUILD b/src/test/java/com/google/devtools/build/lib/worker/BUILD
index d2efeab..c868ab1 100644
--- a/src/test/java/com/google/devtools/build/lib/worker/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/worker/BUILD
@@ -48,6 +48,7 @@
"//src/main/java/com/google/devtools/build/lib/vfs",
"//src/main/java/com/google/devtools/build/lib/vfs:pathfragment",
"//src/main/java/com/google/devtools/build/lib/worker",
+ "//src/main/java/com/google/devtools/build/lib/worker:worker_key",
"//src/main/java/com/google/devtools/build/lib/worker:worker_spawn_runner",
"//src/test/java/com/google/devtools/build/lib/actions/util",
"//third_party:guava",
@@ -97,6 +98,7 @@
"//src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs",
"//src/main/java/com/google/devtools/build/lib/worker",
"//src/main/java/com/google/devtools/build/lib/worker:worker_files_hash",
+ "//src/main/java/com/google/devtools/build/lib/worker:worker_key",
"//src/main/java/com/google/devtools/build/lib/worker:worker_module",
"//src/main/java/com/google/devtools/build/lib/worker:worker_spawn_runner",
"//src/main/java/com/google/devtools/common/options",