Skip to content

Commit b7b2134

Browse files
lberkicopybara-github
authored andcommitted
Separate RemoteAnalysisCacheManager and RemoteAnalysisCacheDeps.
The idea is that the former will be called from BuildTool/BuildView/etc., the rest, from the actual serialization/deserialization machinery. RELNOTES: None. PiperOrigin-RevId: 884327425 Change-Id: I677b39642db872bcbf2e91f35e288cdb3dabfb48
1 parent 01cacec commit b7b2134

File tree

4 files changed

+229
-171
lines changed

4 files changed

+229
-171
lines changed

src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ public void buildTargets(
366366
applyHeuristicInstrumentationFilter(buildOptions, targetPatternPhaseValue);
367367
}
368368
var analysisDeps =
369-
RemoteAnalysisCacheManager.forAnalysis(
369+
RemoteAnalysisCacheManager.create(
370370
env,
371371
projectEvaluationResult.activeDirectoriesMatcher(),
372372
targetPatternPhaseValue.getTargetLabels(),

src/main/java/com/google/devtools/build/lib/skyframe/serialization/analysis/BUILD

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,14 +364,13 @@ java_library(
364364
":analysis_cache_invalidator",
365365
":client_id",
366366
":dependencies_provider",
367-
":event_listener",
368367
":frontier_serializer",
369368
":options",
370369
":remote_analysis_cache_client",
370+
":remote_analysis_cache_deps",
371371
":remote_analysis_caching_server_state",
372372
":remote_analysis_caching_services_supplier",
373373
":remote_analysis_json_log_writer",
374-
":remote_analysis_metadata_writer",
375374
"//src/main/java/com/google/devtools/build/lib/actions:artifacts",
376375
"//src/main/java/com/google/devtools/build/lib/analysis:blaze_directories",
377376
"//src/main/java/com/google/devtools/build/lib/analysis:blaze_version_info",
@@ -406,3 +405,25 @@ java_library(
406405
"//third_party:jsr305",
407406
],
408407
)
408+
409+
java_library(
410+
name = "remote_analysis_cache_deps",
411+
srcs = ["RemoteAnalysisCacheDeps.java"],
412+
deps = [
413+
":dependencies_provider",
414+
":event_listener",
415+
":options",
416+
":remote_analysis_cache_client",
417+
":remote_analysis_caching_services_supplier",
418+
":remote_analysis_json_log_writer",
419+
":remote_analysis_metadata_writer",
420+
"//src/main/java/com/google/devtools/build/lib/cmdline",
421+
"//src/main/java/com/google/devtools/build/lib/events",
422+
"//src/main/java/com/google/devtools/build/lib/skyframe/serialization",
423+
"//src/main/java/com/google/devtools/build/lib/skyframe/serialization:frontier_node_version",
424+
"//src/main/java/com/google/devtools/build/skyframe:skyframe-objects",
425+
"//third_party:flogger",
426+
"//third_party:guava",
427+
"//third_party:jsr305",
428+
],
429+
)
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
// Copyright 2026 The Bazel Authors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.devtools.build.lib.skyframe.serialization.analysis;
16+
17+
import static java.util.concurrent.TimeUnit.SECONDS;
18+
19+
import com.google.common.flogger.GoogleLogger;
20+
import com.google.common.util.concurrent.ListenableFuture;
21+
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
22+
import com.google.devtools.build.lib.events.Event;
23+
import com.google.devtools.build.lib.events.ExtendedEventHandler;
24+
import com.google.devtools.build.lib.skyframe.serialization.FingerprintValueService;
25+
import com.google.devtools.build.lib.skyframe.serialization.FrontierNodeVersion;
26+
import com.google.devtools.build.lib.skyframe.serialization.KeyValueWriter;
27+
import com.google.devtools.build.lib.skyframe.serialization.ObjectCodecs;
28+
import com.google.devtools.build.lib.skyframe.serialization.SerializationException;
29+
import com.google.devtools.build.lib.skyframe.serialization.SkyValueRetriever.RetrievalResult;
30+
import com.google.devtools.build.lib.skyframe.serialization.analysis.RemoteAnalysisCachingDependenciesProvider.SerializationDependenciesProvider;
31+
import com.google.devtools.build.lib.skyframe.serialization.analysis.RemoteAnalysisCachingOptions.RemoteAnalysisCacheMode;
32+
import com.google.devtools.build.skyframe.SkyKey;
33+
import java.util.Optional;
34+
import java.util.concurrent.ExecutionException;
35+
import java.util.concurrent.Future;
36+
import java.util.concurrent.TimeoutException;
37+
import java.util.concurrent.atomic.AtomicBoolean;
38+
import java.util.function.Predicate;
39+
import javax.annotation.Nullable;
40+
41+
class RemoteAnalysisCacheDeps
42+
implements SerializationDependenciesProvider, RemoteAnalysisCacheReaderDepsProvider {
43+
private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();
44+
45+
private static final long CLIENT_LOOKUP_TIMEOUT_SEC = 20L;
46+
47+
private final RemoteAnalysisCacheMode mode;
48+
private final boolean bailOutOnMissingFingerprint;
49+
private final String serializedFrontierProfile;
50+
private final Optional<Predicate<PackageIdentifier>> activeDirectoriesMatcher;
51+
private final RemoteAnalysisCachingEventListener listener;
52+
private final FrontierNodeVersion frontierNodeVersion;
53+
@Nullable private final RemoteAnalysisJsonLogWriter jsonLogWriter;
54+
55+
private final ListenableFuture<ObjectCodecs> objectCodecs;
56+
private final ListenableFuture<FingerprintValueService> fingerprintValueServiceFuture;
57+
@Nullable private final ListenableFuture<? extends RemoteAnalysisCacheClient> analysisCacheClient;
58+
@Nullable private final ListenableFuture<? extends RemoteAnalysisMetadataWriter> metadataWriter;
59+
60+
private final AtomicBoolean bailedOut = new AtomicBoolean();
61+
private final ExtendedEventHandler eventHandler;
62+
63+
RemoteAnalysisCacheDeps(
64+
ExtendedEventHandler eventHandler,
65+
RemoteAnalysisCacheMode mode,
66+
boolean bailOutOnMissingFingerprint,
67+
RemoteAnalysisCachingServicesSupplier servicesSupplier,
68+
RemoteAnalysisCachingEventListener listener,
69+
RemoteAnalysisJsonLogWriter jsonLogWriter,
70+
ListenableFuture<ObjectCodecs> objectCodecs,
71+
FrontierNodeVersion frontierNodeVersion,
72+
Optional<Predicate<PackageIdentifier>> activeDirectoriesMatcher,
73+
String serializedFrontierProfile) {
74+
this.mode = mode;
75+
this.bailOutOnMissingFingerprint = bailOutOnMissingFingerprint;
76+
this.serializedFrontierProfile = serializedFrontierProfile;
77+
this.activeDirectoriesMatcher = activeDirectoriesMatcher;
78+
this.eventHandler = eventHandler;
79+
80+
this.jsonLogWriter = jsonLogWriter;
81+
82+
this.objectCodecs = objectCodecs;
83+
this.listener = listener;
84+
85+
this.frontierNodeVersion = frontierNodeVersion;
86+
87+
this.fingerprintValueServiceFuture = servicesSupplier.getFingerprintValueService();
88+
this.metadataWriter = servicesSupplier.getMetadataWriter();
89+
this.analysisCacheClient = servicesSupplier.getAnalysisCacheClient();
90+
}
91+
92+
static <T> T resolveWithTimeout(Future<? extends T> future, String what)
93+
throws InterruptedException {
94+
if (future == null) {
95+
return null;
96+
}
97+
try {
98+
return future.get(CLIENT_LOOKUP_TIMEOUT_SEC, SECONDS);
99+
} catch (ExecutionException | TimeoutException e) {
100+
logger.atWarning().withCause(e).log("Unable to initialize %s", what);
101+
return null;
102+
}
103+
}
104+
105+
@Override
106+
public RemoteAnalysisCacheMode mode() {
107+
return mode;
108+
}
109+
110+
@Override
111+
public String getSerializedFrontierProfile() {
112+
return serializedFrontierProfile;
113+
}
114+
115+
@Override
116+
public Optional<Predicate<PackageIdentifier>> getActiveDirectoriesMatcher() {
117+
return activeDirectoriesMatcher;
118+
}
119+
120+
@Override
121+
public FrontierNodeVersion getSkyValueVersion() {
122+
return frontierNodeVersion;
123+
}
124+
125+
@Override
126+
public ObjectCodecs getObjectCodecs() throws InterruptedException {
127+
try {
128+
return objectCodecs.get();
129+
} catch (ExecutionException e) {
130+
throw new IllegalStateException("Failed to initialize ObjectCodecs", e);
131+
}
132+
}
133+
134+
@Override
135+
public FingerprintValueService getFingerprintValueService() throws InterruptedException {
136+
return resolveWithTimeout(fingerprintValueServiceFuture, "fingerprint value service");
137+
}
138+
139+
@Override
140+
public KeyValueWriter getFileInvalidationWriter() throws InterruptedException {
141+
return getFingerprintValueService();
142+
}
143+
144+
@Override
145+
@Nullable
146+
public RemoteAnalysisCacheClient getAnalysisCacheClient() throws InterruptedException {
147+
return resolveWithTimeout(analysisCacheClient, "analysis cache client");
148+
}
149+
150+
@Override
151+
@Nullable
152+
public RemoteAnalysisMetadataWriter getMetadataWriter() throws InterruptedException {
153+
return resolveWithTimeout(metadataWriter, "metadata writer");
154+
}
155+
156+
@Nullable
157+
@Override
158+
public RemoteAnalysisJsonLogWriter getJsonLogWriter() {
159+
return jsonLogWriter;
160+
}
161+
162+
@Override
163+
public void recordRetrievalResult(RetrievalResult retrievalResult, SkyKey key) {
164+
listener.recordRetrievalResult(retrievalResult, key);
165+
}
166+
167+
@Override
168+
public void recordSerializationException(SerializationException e, SkyKey key) {
169+
listener.recordSerializationException(e, key);
170+
}
171+
172+
@Override
173+
public boolean shouldBailOutOnMissingFingerprint() {
174+
if (!bailOutOnMissingFingerprint) {
175+
return false;
176+
}
177+
if (bailedOut.get()) {
178+
return true;
179+
}
180+
181+
try {
182+
FingerprintValueService service = getFingerprintValueService();
183+
boolean retVal = service != null && service.getStats().entriesNotFound() > 0;
184+
if (retVal) {
185+
bailedOut.set(true);
186+
eventHandler.handle(
187+
Event.warn(
188+
"Skycache: falling back to local evaluation due to unexpected missing cache"
189+
+ " entries"));
190+
analysisCacheClient.get().bailOutDueToMissingFingerprint();
191+
}
192+
return retVal;
193+
} catch (InterruptedException e) {
194+
Thread.currentThread().interrupt();
195+
return false;
196+
} catch (ExecutionException e) {
197+
throw new IllegalStateException(
198+
"At this point the Skycache client should have been initialized", e);
199+
}
200+
}
201+
}

0 commit comments

Comments
 (0)