Skip to content

Commit 8e359e7

Browse files
Googlercopybara-github
Googler
authored andcommitted
RELNOTES[INC]: Remove high priority workers functionality from blaze.
We don't observe any profit in wall time from high priority workers right now in Goole internally. Moreover for fully-worker builds we see a wall time degradation. PiperOrigin-RevId: 522309316 Change-Id: Ic5ebd3021d33abb043fca6f55edb0dc0468f4bef
1 parent 986863a commit 8e359e7

File tree

11 files changed

+31
-391
lines changed

11 files changed

+31
-391
lines changed

src/main/java/com/google/devtools/build/lib/actions/ResourceManager.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -545,9 +545,7 @@ boolean areResourcesAvailable(ResourceSet resources) throws NoSuchElementExcepti
545545
availableWorkers = this.workerPool.getMaxTotalPerKey(workerKey);
546546
activeWorkers = this.workerPool.getNumActive(workerKey);
547547
}
548-
boolean workerIsAvailable =
549-
workerKey == null
550-
|| (activeWorkers < availableWorkers && workerPool.couldBeBorrowed(workerKey));
548+
boolean workerIsAvailable = workerKey == null || (activeWorkers < availableWorkers);
551549

552550
// We test for tracking of extra resources whenever acquired and throw an
553551
// exception before acquiring any untracked resource.

src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRulesModule.java

+10
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import com.google.devtools.common.options.OptionMetadataTag;
4545
import com.google.devtools.common.options.OptionsBase;
4646
import java.io.IOException;
47+
import java.util.List;
4748

4849
/** Module implementing the rule set of Bazel. */
4950
public final class BazelRulesModule extends BlazeModule {
@@ -289,6 +290,15 @@ public static class BuildGraveyardOptions extends OptionsBase {
289290
effectTags = {OptionEffectTag.NO_OP},
290291
help = "No-op.")
291292
public boolean parseHeadersSkippedIfCorrespondingSrcsFound;
293+
294+
@Option(
295+
name = "high_priority_workers",
296+
defaultValue = "null",
297+
documentationCategory = OptionDocumentationCategory.EXECUTION_STRATEGY,
298+
effectTags = {OptionEffectTag.EXECUTION},
299+
help = "No-op, will be removed soon.",
300+
allowMultiple = true)
301+
public List<String> highPriorityWorkers;
292302
}
293303

294304
/** This is where deprecated Bazel-specific options only used by the build command go to die. */

src/main/java/com/google/devtools/build/lib/worker/WorkerModule.java

+1-4
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,7 @@ public void buildStarting(BuildStartingEvent event) {
145145

146146
WorkerPoolConfig newConfig =
147147
new WorkerPoolConfig(
148-
workerFactory,
149-
options.workerMaxInstances,
150-
options.workerMaxMultiplexInstances,
151-
options.highPriorityWorkers);
148+
workerFactory, options.workerMaxInstances, options.workerMaxMultiplexInstances);
152149

153150
// If the config changed compared to the last run, we have to create a new pool.
154151
if (workerPool == null || !newConfig.equals(workerPool.getWorkerPoolConfig())) {

src/main/java/com/google/devtools/build/lib/worker/WorkerOptions.java

-11
Original file line numberDiff line numberDiff line change
@@ -108,17 +108,6 @@ public String getTypeDescription() {
108108
allowMultiple = true)
109109
public List<Map.Entry<String, Integer>> workerMaxMultiplexInstances;
110110

111-
@Option(
112-
name = "high_priority_workers",
113-
defaultValue = "null",
114-
documentationCategory = OptionDocumentationCategory.EXECUTION_STRATEGY,
115-
effectTags = {OptionEffectTag.EXECUTION},
116-
help =
117-
"Mnemonics of workers to run with high priority. When high priority workers are running "
118-
+ "all other workers are throttled.",
119-
allowMultiple = true)
120-
public List<String> highPriorityWorkers;
121-
122111
@Option(
123112
name = "worker_quit_after_build",
124113
defaultValue = "false",

src/main/java/com/google/devtools/build/lib/worker/WorkerPool.java

-2
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ public interface WorkerPool {
3838

3939
Worker borrowObject(WorkerKey key) throws IOException, InterruptedException;
4040

41-
boolean couldBeBorrowed(WorkerKey key);
42-
4341
void returnObject(WorkerKey key, Worker obj);
4442

4543
void invalidateObject(WorkerKey key, Worker obj) throws InterruptedException;

src/main/java/com/google/devtools/build/lib/worker/WorkerPoolImpl.java

+4-86
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import java.util.Map;
2424
import java.util.Map.Entry;
2525
import java.util.Objects;
26-
import java.util.concurrent.atomic.AtomicInteger;
2726
import javax.annotation.Nonnull;
2827
import javax.annotation.concurrent.ThreadSafe;
2928
import org.apache.commons.pool2.impl.EvictionPolicy;
@@ -37,15 +36,6 @@ public class WorkerPoolImpl implements WorkerPool {
3736
/** Unless otherwise specified, the max number of multiplex workers per WorkerKey. */
3837
private static final int DEFAULT_MAX_MULTIPLEX_WORKERS = 8;
3938

40-
private static final int MAX_NON_BLOCKING_HIGH_PRIORITY_WORKERS = 1;
41-
/**
42-
* How many high-priority workers are currently borrowed. If greater than one, low-priority
43-
* workers cannot be borrowed until the high-priority ones are done.
44-
*/
45-
private final AtomicInteger highPriorityWorkersInUse = new AtomicInteger(0);
46-
/** Which mnemonics create high-priority workers. */
47-
private final ImmutableSet<String> highPriorityWorkerMnemonics;
48-
4939
private final WorkerPoolConfig workerPoolConfig;
5040
/** Map of singleplex worker pools, one per mnemonic. */
5141
private final ImmutableMap<String, SimpleWorkerPool> workerPools;
@@ -58,9 +48,6 @@ public class WorkerPoolImpl implements WorkerPool {
5848
public WorkerPoolImpl(WorkerPoolConfig workerPoolConfig) {
5949
this.workerPoolConfig = workerPoolConfig;
6050

61-
highPriorityWorkerMnemonics =
62-
ImmutableSet.copyOf((Iterable<String>) workerPoolConfig.getHighPriorityWorkers());
63-
6451
ImmutableMap<String, Integer> config =
6552
createConfigFromOptions(workerPoolConfig.getWorkerMaxInstances(), DEFAULT_MAX_WORKERS);
6653
ImmutableMap<String, Integer> multiplexConfig =
@@ -143,8 +130,7 @@ public void evictWithPolicy(EvictionPolicy<Worker> evictionPolicy) throws Interr
143130
}
144131

145132
/**
146-
* Gets a worker. May block indefinitely if too many high-priority workers are in use and the
147-
* requested worker is not high priority.
133+
* Gets a worker from worker pool. Could wait if no idle workers are available.
148134
*
149135
* @param key worker key
150136
* @return a worker
@@ -158,44 +144,11 @@ public Worker borrowObject(WorkerKey key) throws IOException, InterruptedExcepti
158144
Throwables.propagateIfPossible(t, IOException.class, InterruptedException.class);
159145
throw new RuntimeException("unexpected", t);
160146
}
161-
162-
// TODO(b/244297036): move highPriorityWorkerMnemonics logic to the ResourceManager.
163-
if (highPriorityWorkerMnemonics.contains(key.getMnemonic())) {
164-
highPriorityWorkersInUse.incrementAndGet();
165-
} else {
166-
try {
167-
waitForHighPriorityWorkersToFinish();
168-
} catch (InterruptedException e) {
169-
returnObject(key, result);
170-
throw e;
171-
}
172-
}
173-
174147
return result;
175148
}
176149

177-
/**
178-
* Checks if there is no blockers from high priority workers to take new worker with this worker
179-
* key. Doesn't check occupancy of worker pool for this mnemonic.
180-
*/
181-
@Override
182-
public boolean couldBeBorrowed(WorkerKey key) {
183-
if (highPriorityWorkerMnemonics.contains(key.getMnemonic())) {
184-
return true;
185-
}
186-
187-
if (highPriorityWorkersInUse.get() <= MAX_NON_BLOCKING_HIGH_PRIORITY_WORKERS) {
188-
return true;
189-
}
190-
191-
return false;
192-
}
193-
194150
@Override
195151
public void returnObject(WorkerKey key, Worker obj) {
196-
if (highPriorityWorkerMnemonics.contains(key.getMnemonic())) {
197-
decrementHighPriorityWorkerCount();
198-
}
199152
if (doomedWorkers.contains(obj.getWorkerId())) {
200153
obj.setDoomed(true);
201154
}
@@ -204,9 +157,6 @@ public void returnObject(WorkerKey key, Worker obj) {
204157

205158
@Override
206159
public void invalidateObject(WorkerKey key, Worker obj) throws InterruptedException {
207-
if (highPriorityWorkerMnemonics.contains(key.getMnemonic())) {
208-
decrementHighPriorityWorkerCount();
209-
}
210160
if (doomedWorkers.contains(obj.getWorkerId())) {
211161
obj.setDoomed(true);
212162
}
@@ -218,29 +168,6 @@ public void invalidateObject(WorkerKey key, Worker obj) throws InterruptedExcept
218168
}
219169
}
220170

221-
// Decrements the high-priority workers counts and pings waiting threads if appropriate.
222-
private void decrementHighPriorityWorkerCount() {
223-
if (highPriorityWorkersInUse.decrementAndGet() <= MAX_NON_BLOCKING_HIGH_PRIORITY_WORKERS) {
224-
synchronized (highPriorityWorkersInUse) {
225-
highPriorityWorkersInUse.notifyAll();
226-
}
227-
}
228-
}
229-
230-
// Returns once less than two high-priority workers are running.
231-
private void waitForHighPriorityWorkersToFinish() throws InterruptedException {
232-
// Fast path for the case where the high-priority workers feature is not in use.
233-
if (highPriorityWorkerMnemonics.isEmpty()) {
234-
return;
235-
}
236-
237-
while (highPriorityWorkersInUse.get() > MAX_NON_BLOCKING_HIGH_PRIORITY_WORKERS) {
238-
synchronized (highPriorityWorkersInUse) {
239-
highPriorityWorkersInUse.wait();
240-
}
241-
}
242-
}
243-
244171
@Override
245172
public synchronized void setDoomedWorkers(ImmutableSet<Integer> workerIds) {
246173
this.doomedWorkers = workerIds;
@@ -280,17 +207,14 @@ public static class WorkerPoolConfig {
280207
private final WorkerFactory workerFactory;
281208
private final List<Entry<String, Integer>> workerMaxInstances;
282209
private final List<Entry<String, Integer>> workerMaxMultiplexInstances;
283-
private final List<String> highPriorityWorkers;
284210

285211
public WorkerPoolConfig(
286212
WorkerFactory workerFactory,
287213
List<Entry<String, Integer>> workerMaxInstances,
288-
List<Entry<String, Integer>> workerMaxMultiplexInstances,
289-
List<String> highPriorityWorkers) {
214+
List<Entry<String, Integer>> workerMaxMultiplexInstances) {
290215
this.workerFactory = workerFactory;
291216
this.workerMaxInstances = workerMaxInstances;
292217
this.workerMaxMultiplexInstances = workerMaxMultiplexInstances;
293-
this.highPriorityWorkers = highPriorityWorkers;
294218
}
295219

296220
public WorkerFactory getWorkerFactory() {
@@ -305,10 +229,6 @@ public List<Entry<String, Integer>> getWorkerMaxMultiplexInstances() {
305229
return workerMaxMultiplexInstances;
306230
}
307231

308-
public List<String> getHighPriorityWorkers() {
309-
return highPriorityWorkers;
310-
}
311-
312232
@Override
313233
public boolean equals(Object o) {
314234
if (this == o) {
@@ -320,14 +240,12 @@ public boolean equals(Object o) {
320240
WorkerPoolConfig that = (WorkerPoolConfig) o;
321241
return workerFactory.equals(that.workerFactory)
322242
&& workerMaxInstances.equals(that.workerMaxInstances)
323-
&& workerMaxMultiplexInstances.equals(that.workerMaxMultiplexInstances)
324-
&& highPriorityWorkers.equals(that.highPriorityWorkers);
243+
&& workerMaxMultiplexInstances.equals(that.workerMaxMultiplexInstances);
325244
}
326245

327246
@Override
328247
public int hashCode() {
329-
return Objects.hash(
330-
workerFactory, workerMaxInstances, workerMaxMultiplexInstances, highPriorityWorkers);
248+
return Objects.hash(workerFactory, workerMaxInstances, workerMaxMultiplexInstances);
331249
}
332250
}
333251
}

src/test/java/com/google/devtools/build/lib/actions/ResourceManagerTest.java

-98
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,8 @@
4141
import com.google.devtools.build.lib.worker.WorkerPoolImpl;
4242
import com.google.errorprone.annotations.CanIgnoreReturnValue;
4343
import java.io.IOException;
44-
import java.time.Duration;
4544
import java.util.Collection;
4645
import java.util.NoSuchElementException;
47-
import java.util.concurrent.CountDownLatch;
4846
import java.util.concurrent.CyclicBarrier;
4947
import java.util.concurrent.TimeUnit;
5048
import java.util.concurrent.atomic.AtomicInteger;
@@ -101,7 +99,6 @@ public boolean validateObject(WorkerKey key, PooledObject<Worker> p) {
10199
}
102100
},
103101
ImmutableList.of(),
104-
ImmutableList.of(),
105102
ImmutableList.of()));
106103
}
107104

@@ -759,101 +756,6 @@ public void testAcquireWithWorker_acquireAndRelease() throws Exception {
759756
assertThat(rm.inUse()).isFalse();
760757
}
761758

762-
@Test
763-
public void testReleaseWorker_highPriorityWorker() throws Exception {
764-
765-
String slowMenmonic = "SLOW";
766-
String fastMenmonic = "FAST";
767-
768-
Worker slowWorker1 = mock(Worker.class);
769-
Worker slowWorker2 = mock(Worker.class);
770-
Worker fastWorker = mock(Worker.class);
771-
772-
WorkerKey slowWorkerKey = createWorkerKey(slowMenmonic);
773-
WorkerKey fastWorkerKey = createWorkerKey(fastMenmonic);
774-
775-
when(slowWorker1.getWorkerKey()).thenReturn(slowWorkerKey);
776-
when(slowWorker2.getWorkerKey()).thenReturn(slowWorkerKey);
777-
when(fastWorker.getWorkerKey()).thenReturn(fastWorkerKey);
778-
779-
CountDownLatch slowLatch = new CountDownLatch(2);
780-
CountDownLatch fastLatch = new CountDownLatch(1);
781-
782-
WorkerPoolImpl workerPool =
783-
new WorkerPoolImpl(
784-
new WorkerPoolImpl.WorkerPoolConfig(
785-
new WorkerFactory(fs.getPath("/workerBase")) {
786-
int numOfSlowWorkers = 0;
787-
788-
@Override
789-
public Worker create(WorkerKey key) {
790-
assertThat(key.getMnemonic()).isAnyOf(slowMenmonic, fastMenmonic);
791-
792-
if (key.getMnemonic().equals(fastMenmonic)) {
793-
return fastWorker;
794-
}
795-
796-
assertThat(numOfSlowWorkers).isLessThan(2);
797-
798-
if (numOfSlowWorkers == 0) {
799-
numOfSlowWorkers++;
800-
return slowWorker1;
801-
}
802-
803-
numOfSlowWorkers++;
804-
return slowWorker2;
805-
}
806-
807-
@Override
808-
public boolean validateObject(WorkerKey key, PooledObject<Worker> p) {
809-
return true;
810-
}
811-
},
812-
ImmutableList.of(),
813-
ImmutableList.of(),
814-
/* highPriorityWorkers= */ ImmutableList.of(slowMenmonic)));
815-
rm.setWorkerPool(workerPool);
816-
817-
TestThread slowThread1 =
818-
new TestThread(
819-
() -> {
820-
ResourceHandle handle = acquire(100, 0.1, 0, slowMenmonic);
821-
slowLatch.countDown();
822-
fastLatch.await();
823-
// release resources
824-
handle.close();
825-
});
826-
827-
TestThread slowThread2 =
828-
new TestThread(
829-
() -> {
830-
ResourceHandle handle = acquire(100, 0.1, 0, slowMenmonic);
831-
slowLatch.countDown();
832-
fastLatch.await();
833-
// release resources
834-
handle.close();
835-
});
836-
837-
TestThread fastThread =
838-
new TestThread(
839-
() -> {
840-
slowLatch.await();
841-
assertThat(isAvailable(rm, 100, 0.1, 0, createWorkerKey(fastMenmonic))).isFalse();
842-
fastLatch.countDown();
843-
ResourceHandle handle = acquire(100, 0.1, 0, fastMenmonic);
844-
// release resources
845-
handle.close();
846-
});
847-
848-
slowThread1.start();
849-
slowThread2.start();
850-
fastThread.start();
851-
852-
slowThread1.joinAndAssertState(Duration.ofSeconds(10).toMillis());
853-
slowThread2.joinAndAssertState(Duration.ofSeconds(10).toMillis());
854-
fastThread.joinAndAssertState(Duration.ofSeconds(10).toMillis());
855-
}
856-
857759
synchronized boolean isAvailable(ResourceManager rm, double ram, double cpu, int localTestCount) {
858760
return rm.areResourcesAvailable(ResourceSet.create(ram, cpu, localTestCount));
859761
}

0 commit comments

Comments
 (0)