Skip to content

Commit 595866a

Browse files
Ian Childsfacebook-github-bot
Ian Childs
authored andcommitted
Decouple remote dep file cache checking from action cache checking
Summary: Previously, we just had one `cache_checker`, and if the action cache lookup failed, and remote dep file lookup was enabled, then we'd do a remote dep file lookup from within the action cache checker. I want to change the order of the lookups that we do so that we check the local dep file cache before we do a remote dep file lookup, so this diff decouples the remote dep file lookup from the action cache lookup (but doesn't yet change the order). Now, we do two explicit calls in `run.rs`, first to the action cache and then to the remote dep file cache. Reviewed By: blackm00n Differential Revision: D74064170 fbshipit-source-id: 10c561ebe06dc87131a3eb113fa43cfdad78e051
1 parent 8706f6e commit 595866a

File tree

10 files changed

+137
-67
lines changed

10 files changed

+137
-67
lines changed

app/buck2_action_impl/src/actions/impls/run.rs

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -674,19 +674,27 @@ impl RunAction {
674674

675675
let action_cache_result = ctx.action_cache(manager, &req, &prepared_action).await;
676676

677-
// If the result was served by the remote dep file cache, we can't use the result just yet. We need to verify that
678-
// the inputs tracked by a depfile that was actually used in the cache hit are indentical to the inputs we have for this action.
679-
let result = if let ControlFlow::Break(res) = action_cache_result {
680-
self.check_cache_result_is_useable(
681-
ctx,
682-
&req,
683-
&prepared_action.action_and_blobs.action,
684-
res,
685-
&dep_file_bundle,
686-
)
687-
.await?
688-
} else {
689-
action_cache_result
677+
let result = match action_cache_result {
678+
ControlFlow::Break(_) => action_cache_result,
679+
ControlFlow::Continue(manager) => {
680+
let remote_dep_file_result = ctx
681+
.remote_dep_file_cache(manager, &req, &prepared_action)
682+
.await;
683+
if let ControlFlow::Break(res) = remote_dep_file_result {
684+
// If the result was served by the remote dep file cache, we can't use the result just yet. We need to verify that
685+
// the inputs tracked by a depfile that was actually used in the cache hit are identical to the inputs we have for this action.
686+
self.check_cache_result_is_useable(
687+
ctx,
688+
&req,
689+
&prepared_action.action_and_blobs.action,
690+
res,
691+
&dep_file_bundle,
692+
)
693+
.await?
694+
} else {
695+
remote_dep_file_result
696+
}
697+
}
690698
};
691699

692700
// If the cache queries did not yield to a result, fallback to local dep file query (continuation), then execution.

app/buck2_build_api/src/actions.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,13 @@ pub trait ActionExecutionCtx: Send + Sync {
213213
prepared_action: &PreparedAction,
214214
) -> ControlFlow<CommandExecutionResult, CommandExecutionManager>;
215215

216+
async fn remote_dep_file_cache(
217+
&mut self,
218+
manager: CommandExecutionManager,
219+
request: &CommandExecutionRequest,
220+
prepared_action: &PreparedAction,
221+
) -> ControlFlow<CommandExecutionResult, CommandExecutionManager>;
222+
216223
async fn cache_upload(
217224
&mut self,
218225
action: &ActionDigestAndBlobs,

app/buck2_build_api/src/actions/execute/action_executor.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,8 @@ impl HasActionExecutor for DiceComputations<'_> {
241241
let CommandExecutorResponse {
242242
executor,
243243
platform,
244-
cache_checker,
244+
action_cache_checker,
245+
remote_dep_file_cache_checker,
245246
cache_uploader,
246247
} = self.get_command_executor_from_dice(executor_config).await?;
247248
let blocking_executor = self.get_blocking_executor();
@@ -257,7 +258,8 @@ impl HasActionExecutor for DiceComputations<'_> {
257258
Ok(Arc::new(BuckActionExecutor::new(
258259
CommandExecutor::new(
259260
executor,
260-
cache_checker,
261+
action_cache_checker,
262+
remote_dep_file_cache_checker,
261263
cache_uploader,
262264
artifact_fs,
263265
executor_config.options,
@@ -423,6 +425,28 @@ impl ActionExecutionCtx for BuckActionExecutionContext<'_> {
423425
.await
424426
}
425427

428+
async fn remote_dep_file_cache(
429+
&mut self,
430+
manager: CommandExecutionManager,
431+
request: &CommandExecutionRequest,
432+
prepared_action: &PreparedAction,
433+
) -> ControlFlow<CommandExecutionResult, CommandExecutionManager> {
434+
let action = self.target();
435+
self.executor
436+
.command_executor
437+
.remote_dep_file_cache(
438+
manager,
439+
&PreparedCommand {
440+
target: &action as _,
441+
request,
442+
prepared_action,
443+
digest_config: self.digest_config(),
444+
},
445+
self.cancellations,
446+
)
447+
.await
448+
}
449+
426450
fn unpack_command_execution_result(
427451
&mut self,
428452
executor_preference: ExecutorPreference,
@@ -774,6 +798,7 @@ mod tests {
774798
CommandExecutor::new(
775799
Arc::new(DryRunExecutor::new(tracker, artifact_fs.clone())),
776800
Arc::new(NoOpCommandOptionalExecutor {}),
801+
Arc::new(NoOpCommandOptionalExecutor {}),
777802
Arc::new(NoOpCacheUploader {}),
778803
artifact_fs,
779804
CommandGenerationOptions {

app/buck2_build_api/src/actions/execute/dice_data.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ use crate::actions::artifact::get_artifact_fs::GetArtifactFs;
3232
pub struct CommandExecutorResponse {
3333
pub executor: Arc<dyn PreparedCommandExecutor>,
3434
pub platform: RE::Platform,
35-
pub cache_checker: Arc<dyn PreparedCommandOptionalExecutor>,
35+
pub action_cache_checker: Arc<dyn PreparedCommandOptionalExecutor>,
36+
pub remote_dep_file_cache_checker: Arc<dyn PreparedCommandOptionalExecutor>,
3637
pub cache_uploader: Arc<dyn UploadCache>,
3738
}
3839

app/buck2_build_api_tests/src/actions/calculation.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,8 @@ async fn make_default_dice_state(
220220
));
221221
Ok(CommandExecutorResponse {
222222
executor,
223-
cache_checker: Arc::new(NoOpCommandOptionalExecutor {}),
223+
action_cache_checker: Arc::new(NoOpCommandOptionalExecutor {}),
224+
remote_dep_file_cache_checker: Arc::new(NoOpCommandOptionalExecutor {}),
224225
platform: Default::default(),
225226
cache_uploader: Arc::new(NoOpCacheUploader {}),
226227
})

app/buck2_execute/src/execute/command_executor.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ pub struct CommandExecutor(Arc<CommandExecutorData>);
7777

7878
struct CommandExecutorData {
7979
inner: Arc<dyn PreparedCommandExecutor>,
80-
cache_checker: Arc<dyn PreparedCommandOptionalExecutor>,
80+
action_cache_checker: Arc<dyn PreparedCommandOptionalExecutor>,
81+
remote_dep_file_cache_checker: Arc<dyn PreparedCommandOptionalExecutor>,
8182
artifact_fs: ArtifactFs,
8283
options: CommandGenerationOptions,
8384
re_platform: RE::Platform,
@@ -87,15 +88,17 @@ struct CommandExecutorData {
8788
impl CommandExecutor {
8889
pub fn new(
8990
inner: Arc<dyn PreparedCommandExecutor>,
90-
cache_checker: Arc<dyn PreparedCommandOptionalExecutor>,
91+
action_cache_checker: Arc<dyn PreparedCommandOptionalExecutor>,
92+
remote_dep_file_cache_checker: Arc<dyn PreparedCommandOptionalExecutor>,
9193
cache_uploader: Arc<dyn UploadCache>,
9294
artifact_fs: ArtifactFs,
9395
options: CommandGenerationOptions,
9496
re_platform: RE::Platform,
9597
) -> Self {
9698
Self(Arc::new(CommandExecutorData {
9799
inner,
98-
cache_checker,
100+
action_cache_checker,
101+
remote_dep_file_cache_checker,
99102
artifact_fs,
100103
options,
101104
re_platform,
@@ -123,7 +126,19 @@ impl CommandExecutor {
123126
cancellations: &CancellationContext,
124127
) -> ControlFlow<CommandExecutionResult, CommandExecutionManager> {
125128
self.0
126-
.cache_checker
129+
.action_cache_checker
130+
.maybe_execute(prepared_command, manager, cancellations)
131+
.await
132+
}
133+
134+
pub async fn remote_dep_file_cache(
135+
&self,
136+
manager: CommandExecutionManager,
137+
prepared_command: &PreparedCommand<'_, '_>,
138+
cancellations: &CancellationContext,
139+
) -> ControlFlow<CommandExecutionResult, CommandExecutionManager> {
140+
self.0
141+
.remote_dep_file_cache_checker
127142
.maybe_execute(prepared_command, manager, cancellations)
128143
.await
129144
}

app/buck2_execute_impl/src/executors/action_cache.rs

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ pub struct ActionCacheChecker {
4747
pub upload_all_actions: bool,
4848
pub knobs: ExecutorGlobalKnobs,
4949
pub paranoid: Option<ParanoidDownloader>,
50-
pub remote_dep_file_checker: Arc<dyn PreparedCommandOptionalExecutor>,
5150
}
5251

5352
enum CacheType {
@@ -234,7 +233,7 @@ impl PreparedCommandOptionalExecutor for ActionCacheChecker {
234233
&cache_type,
235234
details.clone(),
236235
));
237-
let result = query_action_cache_and_download_result(
236+
query_action_cache_and_download_result(
238237
cache_type,
239238
&self.artifact_fs,
240239
&self.materializer,
@@ -249,17 +248,7 @@ impl PreparedCommandOptionalExecutor for ActionCacheChecker {
249248
self.knobs.log_action_keys,
250249
details,
251250
)
252-
.await;
253-
254-
// If continue (not a cache hit), invoke the remote dep file cache checker
255-
match result {
256-
ControlFlow::Continue(manager) => {
257-
self.remote_dep_file_checker
258-
.maybe_execute(command, manager, cancellations)
259-
.await
260-
}
261-
ControlFlow::Break(result) => ControlFlow::Break(result),
262-
}
251+
.await
263252
}
264253
}
265254

app/buck2_execute_impl/src/executors/stacked.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ use buck2_execute::execute::result::CommandExecutionResult;
1717
use buck2_futures::cancellation::CancellationContext;
1818

1919
pub struct StackedExecutor<O, F> {
20-
pub optional: O,
20+
pub optional1: O,
21+
pub optional2: O,
2122
pub fallback: F,
2223
}
2324

@@ -34,7 +35,11 @@ where
3435
cancellations: &CancellationContext,
3536
) -> CommandExecutionResult {
3637
let manager = self
37-
.optional
38+
.optional1
39+
.maybe_execute(command, manager, cancellations)
40+
.await?; // This actually returns if we get a response.
41+
let manager = self
42+
.optional2
3843
.maybe_execute(command, manager, cancellations)
3944
.await?; // This actually returns if we get a response.
4045

app/buck2_server/src/daemon/common.rs

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,8 @@ impl HasCommandExecutor for CommandExecutorFactory {
206206
return Ok(CommandExecutorResponse {
207207
executor: Arc::new(local_executor_new(&LocalExecutorOptions::default())),
208208
platform: Default::default(),
209-
cache_checker: Arc::new(NoOpCommandOptionalExecutor {}),
209+
action_cache_checker: Arc::new(NoOpCommandOptionalExecutor {}),
210+
remote_dep_file_cache_checker: Arc::new(NoOpCommandOptionalExecutor {}),
210211
cache_uploader: Arc::new(NoOpCacheUploader {}),
211212
});
212213
}
@@ -243,7 +244,8 @@ impl HasCommandExecutor for CommandExecutorFactory {
243244
Some(CommandExecutorResponse {
244245
executor: Arc::new(local_executor_new(local)),
245246
platform: Default::default(),
246-
cache_checker: Arc::new(NoOpCommandOptionalExecutor {}),
247+
action_cache_checker: Arc::new(NoOpCommandOptionalExecutor {}),
248+
remote_dep_file_cache_checker: Arc::new(NoOpCommandOptionalExecutor {}),
247249
cache_uploader: Arc::new(NoOpCacheUploader {}),
248250
})
249251
}
@@ -268,12 +270,15 @@ impl HasCommandExecutor for CommandExecutorFactory {
268270
applicability = testing
269271
)?;
270272

271-
let cache_checker_new = || -> Arc<dyn PreparedCommandOptionalExecutor> {
273+
let cache_checker_new = || -> (Arc<dyn PreparedCommandOptionalExecutor>, Arc<dyn PreparedCommandOptionalExecutor>) {
272274
if disable_caching {
273-
return Arc::new(NoOpCommandOptionalExecutor {}) as _;
275+
return (
276+
Arc::new(NoOpCommandOptionalExecutor {}) as _,
277+
Arc::new(NoOpCommandOptionalExecutor {}) as _,
278+
);
274279
}
275280

276-
let remote_dep_file_checker: Arc<dyn PreparedCommandOptionalExecutor> =
281+
let remote_dep_file_cache_checker: Arc<dyn PreparedCommandOptionalExecutor> =
277282
if remote_options.remote_dep_file_cache_enabled {
278283
Arc::new(RemoteDepFileCacheChecker {
279284
artifact_fs: artifact_fs.clone(),
@@ -288,20 +293,22 @@ impl HasCommandExecutor for CommandExecutorFactory {
288293
Arc::new(NoOpCommandOptionalExecutor {}) as _
289294
};
290295

291-
if only_remote_dep_file_cache {
292-
remote_dep_file_checker
293-
} else {
294-
Arc::new(ActionCacheChecker {
295-
artifact_fs: artifact_fs.clone(),
296-
materializer: self.materializer.dupe(),
297-
re_client: self.get_prepared_re_client(remote_options.re_use_case),
298-
re_action_key: remote_options.re_action_key.clone(),
299-
upload_all_actions: self.upload_all_actions,
300-
knobs: self.executor_global_knobs.dupe(),
301-
paranoid: self.paranoid.dupe(),
302-
remote_dep_file_checker,
303-
}) as _
304-
}
296+
let action_cache_checker: Arc<dyn PreparedCommandOptionalExecutor> =
297+
if only_remote_dep_file_cache {
298+
Arc::new(NoOpCommandOptionalExecutor {}) as _
299+
} else {
300+
Arc::new(ActionCacheChecker {
301+
artifact_fs: artifact_fs.clone(),
302+
materializer: self.materializer.dupe(),
303+
re_client: self.get_prepared_re_client(remote_options.re_use_case),
304+
re_action_key: remote_options.re_action_key.clone(),
305+
upload_all_actions: self.upload_all_actions,
306+
knobs: self.executor_global_knobs.dupe(),
307+
paranoid: self.paranoid.dupe(),
308+
}) as _
309+
};
310+
311+
(action_cache_checker, remote_dep_file_cache_checker)
305312
};
306313

307314
let executor: Option<Arc<dyn PreparedCommandExecutor>> =
@@ -343,10 +350,13 @@ impl HasCommandExecutor for CommandExecutorFactory {
343350
let executor_preference = executor_preference
344351
.and(ExecutorPreference::DefaultErasePreferences)?;
345352

353+
let (action_cache_checker, remote_dep_file_cache_checker) =
354+
cache_checker_new();
346355
Some(Arc::new(HybridExecutor {
347356
local,
348357
remote: StackedExecutor {
349-
optional: cache_checker_new(),
358+
optional1: action_cache_checker,
359+
optional2: remote_dep_file_cache_checker,
350360
fallback: remote,
351361
},
352362
level: HybridExecutionLevel::Full {
@@ -375,11 +385,15 @@ impl HasCommandExecutor for CommandExecutorFactory {
375385
_ => None,
376386
};
377387

378-
let cache_checker = if self.paranoid.is_some() {
379-
Arc::new(NoOpCommandOptionalExecutor {}) as _
380-
} else {
381-
cache_checker_new()
382-
};
388+
let (action_cache_checker, remote_dep_file_cache_checker) =
389+
if self.paranoid.is_some() {
390+
(
391+
Arc::new(NoOpCommandOptionalExecutor {}) as _,
392+
Arc::new(NoOpCommandOptionalExecutor {}) as _,
393+
)
394+
} else {
395+
cache_checker_new()
396+
};
383397

384398
let cache_uploader = if force_cache_upload()? {
385399
Arc::new(CacheUploader::new(
@@ -410,7 +424,8 @@ impl HasCommandExecutor for CommandExecutorFactory {
410424
executor.map(|executor| CommandExecutorResponse {
411425
executor,
412426
platform: remote_options.re_properties.to_re_platform(),
413-
cache_checker,
427+
action_cache_checker,
428+
remote_dep_file_cache_checker,
414429
cache_uploader,
415430
})
416431
}

0 commit comments

Comments
 (0)