Skip to content

Commit 8193bf9

Browse files
committed
ReActionIdentity: make target and paths optional
Instead of making 'identity' optional in some of the request paths, make the fields inside ReActionIdentity optional instead. This enables us to mandate 'identity' for all call RBE client consumer. We simplify the creation of the identity by introducing a minimal constructor to use in different places with insufficient data to build a full one. This change is based on facebook#1169
1 parent 2376d52 commit 8193bf9

File tree

9 files changed

+96
-33
lines changed

9 files changed

+96
-33
lines changed

app/buck2_build_api/src/materialize.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use buck2_common::legacy_configs::key::BuckconfigKeyRef;
1919
use buck2_common::legacy_configs::view::LegacyBuckConfigView;
2020
use buck2_core::execution_types::executor_config::RemoteExecutorUseCase;
2121
use buck2_core::fs::project_rel_path::ProjectRelativePath;
22+
use buck2_directory::directory::fingerprinted_directory::FingerprintedDirectory;
2223
use buck2_error::BuckErrorContext;
2324
use buck2_execute::artifact::artifact_dyn::ArtifactDyn;
2425
use buck2_execute::artifact_utils::ArtifactValueBuilder;
@@ -27,6 +28,7 @@ use buck2_execute::digest_config::HasDigestConfig;
2728
use buck2_execute::directory::ActionDirectoryBuilder;
2829
use buck2_execute::execute::blobs::ActionBlobs;
2930
use buck2_execute::materialize::materializer::HasMaterializer;
31+
use buck2_execute::re::action_identity::ReActionIdentity;
3032
use dashmap::DashSet;
3133
use dice::DiceComputations;
3234
use dice::UserComputationData;
@@ -190,7 +192,10 @@ async fn ensure_uploaded(
190192
&ActionBlobs::new(digest_config),
191193
ProjectRelativePath::empty(),
192194
&dir,
193-
None,
195+
&ReActionIdentity::minimal(
196+
dir.fingerprint().raw_digest().to_string(),
197+
Some(dir.fingerprint().raw_digest().to_string()),
198+
),
194199
digest_config,
195200
ctx.per_transaction_data()
196201
.get_run_action_knobs()

app/buck2_execute/src/re/action_identity.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::execute::target::CommandExecutionTarget;
1717
pub struct ReActionIdentity<'a> {
1818
/// This is currently unused, but historically it has been useful to add logging in the RE
1919
/// client, so it's worth keeping around.
20-
_target: &'a dyn CommandExecutionTarget,
20+
_target: Option<&'a dyn CommandExecutionTarget>,
2121

2222
/// Actions with the same action key share e.g. memory requirements learnt by RE.
2323
pub action_key: String,
@@ -26,7 +26,7 @@ pub struct ReActionIdentity<'a> {
2626
pub affinity_key: String,
2727

2828
/// Details about the action collected while uploading
29-
pub paths: &'a CommandExecutionPaths,
29+
pub paths: Option<&'a CommandExecutionPaths>,
3030

3131
/// Optional action id (usually the action digest hash) used for request metadata.
3232
pub action_id: Option<String>,
@@ -58,15 +58,31 @@ impl<'a> ReActionIdentity<'a> {
5858
let configuration_hash = target.configuration_hash();
5959

6060
Self {
61-
_target: target,
61+
_target: Some(target),
6262
action_key,
6363
affinity_key: target.re_affinity_key(),
64-
paths,
64+
paths: Some(paths),
6565
action_id,
6666
action_mnemonic,
6767
target_label,
6868
configuration_hash,
6969
trace_id,
7070
}
7171
}
72+
73+
/// Create a minimal identity for operations that don't have a full action context,
74+
/// such as permission checks.
75+
pub fn minimal(action_key: String, action_id: Option<String>) -> Self {
76+
Self {
77+
_target: None,
78+
action_key,
79+
affinity_key: String::new(),
80+
paths: None,
81+
action_id,
82+
action_mnemonic: None,
83+
target_label: None,
84+
configuration_hash: None,
85+
trace_id: get_dispatcher().trace_id().to_owned(),
86+
}
87+
}
7288
}

app/buck2_execute/src/re/client.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ impl RemoteExecutionClient {
238238
dir_path: &ProjectRelativePath,
239239
input_dir: &ActionImmutableDirectory,
240240
use_case: RemoteExecutorUseCase,
241-
identity: Option<&ReActionIdentity<'_>>,
241+
identity: &ReActionIdentity<'_>,
242242
digest_config: DigestConfig,
243243
deduplicate_get_digests_ttl_calls: bool,
244244
) -> buck2_error::Result<UploadStats> {
@@ -268,6 +268,7 @@ impl RemoteExecutionClient {
268268
directories: Vec<remote_execution::Path>,
269269
inlined_blobs_with_digest: Vec<InlinedBlobWithDigest>,
270270
use_case: RemoteExecutorUseCase,
271+
identity: &ReActionIdentity<'_>,
271272
) -> buck2_error::Result<()> {
272273
self.data
273274
.uploads
@@ -276,6 +277,7 @@ impl RemoteExecutionClient {
276277
directories,
277278
inlined_blobs_with_digest,
278279
use_case,
280+
identity,
279281
))
280282
.await
281283
}
@@ -960,14 +962,19 @@ impl RemoteExecutionClientImpl {
960962
directories: Vec<remote_execution::Path>,
961963
inlined_blobs_with_digest: Vec<InlinedBlobWithDigest>,
962964
use_case: RemoteExecutorUseCase,
965+
identity: &ReActionIdentity<'_>,
963966
) -> buck2_error::Result<()> {
967+
let mut metadata = use_case.metadata(Some(identity));
968+
if let Some(action_id) = identity.action_id.as_ref() {
969+
metadata.action_id = Some(action_id.clone());
970+
}
964971
with_error_handler(
965972
"upload_files_and_directories",
966973
self.get_session_id(),
967974
self.client()
968975
.get_cas_client()
969976
.upload(
970-
use_case.metadata(None),
977+
metadata,
971978
UploadRequest {
972979
files_with_digest: Some(files_with_digest),
973980
inlined_blobs_with_digest: Some(inlined_blobs_with_digest),
@@ -1329,7 +1336,10 @@ impl RemoteExecutionClientImpl {
13291336
host_runtime_requirements: THostRuntimeRequirements {
13301337
platform: re_platform(platform),
13311338
host_resource_requirements: THostResourceRequirements {
1332-
input_files_bytes: identity.paths.input_files_bytes() as i64,
1339+
input_files_bytes: identity
1340+
.paths
1341+
.map(|p| p.input_files_bytes() as i64)
1342+
.unwrap_or(0),
13331343
resource_units: re_resource_units.unwrap_or_default(),
13341344
..Default::default()
13351345
},

app/buck2_execute/src/re/manager.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ impl ManagedRemoteExecutionClient {
379379
blobs: &ActionBlobs,
380380
dir_path: &ProjectRelativePath,
381381
input_dir: &ActionImmutableDirectory,
382-
identity: Option<&ReActionIdentity<'_>>,
382+
identity: &ReActionIdentity<'_>,
383383
digest_config: DigestConfig,
384384
deduplicate_get_digests_ttl_calls: bool,
385385
) -> buck2_error::Result<UploadStats> {
@@ -405,6 +405,7 @@ impl ManagedRemoteExecutionClient {
405405
files_with_digest: Vec<NamedDigest>,
406406
directories: Vec<remote_execution::Path>,
407407
inlined_blobs_with_digest: Vec<InlinedBlobWithDigest>,
408+
identity: &ReActionIdentity<'_>,
408409
) -> buck2_error::Result<()> {
409410
self.lock()?
410411
.get()
@@ -414,6 +415,7 @@ impl ManagedRemoteExecutionClient {
414415
directories,
415416
inlined_blobs_with_digest,
416417
self.use_case,
418+
identity,
417419
)
418420
.await
419421
}

app/buck2_execute/src/re/uploader.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ impl Uploader {
8282
input_dir: &'a ActionImmutableDirectory,
8383
blobs: &'a ActionBlobs,
8484
use_case: &RemoteExecutorUseCase,
85-
identity: Option<&ReActionIdentity<'_>>,
85+
identity: &ReActionIdentity<'_>,
8686
digest_config: DigestConfig,
8787
deduplicate_get_digests_ttl_calls: bool,
8888
) -> buck2_error::Result<(
@@ -175,8 +175,8 @@ impl Uploader {
175175
})
176176
} else {
177177
let client = client.clone();
178-
let mut metadata = use_case.metadata(identity);
179-
if let Some(id) = identity.and_then(|id| id.action_id.clone()) {
178+
let mut metadata = use_case.metadata(Some(identity));
179+
if let Some(id) = identity.action_id.clone() {
180180
metadata.action_id = Some(id);
181181
}
182182
let request = GetDigestsTtlRequest {
@@ -236,7 +236,7 @@ impl Uploader {
236236
input_dir: &ActionImmutableDirectory,
237237
blobs: &ActionBlobs,
238238
use_case: RemoteExecutorUseCase,
239-
identity: Option<&ReActionIdentity<'_>>,
239+
identity: &ReActionIdentity<'_>,
240240
digest_config: DigestConfig,
241241
deduplicate_get_digests_ttl_calls: bool,
242242
) -> buck2_error::Result<UploadStats> {
@@ -435,8 +435,8 @@ impl Uploader {
435435

436436
// Upload
437437
if !upload_files.is_empty() || !upload_blobs.is_empty() {
438-
let mut metadata = use_case.metadata(identity);
439-
if let Some(id) = identity.and_then(|id| id.action_id.clone()) {
438+
let mut metadata = use_case.metadata(Some(identity));
439+
if let Some(id) = identity.action_id.clone() {
440440
metadata.action_id = Some(id);
441441
}
442442
with_error_handler(
@@ -597,7 +597,7 @@ impl<'s> GetDigestsTtlDeduper<'s> {
597597
deduper: &'s Mutex<Self>,
598598
client: &'a RemoteExecutionClient,
599599
use_case: RemoteExecutorUseCase,
600-
identity: Option<&'a ReActionIdentity<'a>>,
600+
identity: &'a ReActionIdentity<'a>,
601601
digest_config: DigestConfig,
602602
digests: impl IntoIterator<Item = &'a TrackedFileDigest>,
603603
) -> (
@@ -669,13 +669,13 @@ fn query_digest_ttls<'s>(
669669
request_id: RequestId,
670670
client: &RemoteExecutionClient,
671671
use_case: RemoteExecutorUseCase,
672-
identity: Option<&ReActionIdentity<'_>>,
672+
identity: &ReActionIdentity<'_>,
673673
digest_config: DigestConfig,
674674
input_digests: Vec<TrackedFileDigest>,
675675
) -> BoxFuture<'s, buck2_error::Result<HashMap<TrackedFileDigest, i64>>> {
676676
let client = client.dupe();
677-
let mut metadata = use_case.metadata(identity);
678-
if let Some(id) = identity.and_then(|id| id.action_id.clone()) {
677+
let mut metadata = use_case.metadata(Some(identity));
678+
if let Some(id) = identity.action_id.clone() {
679679
metadata.action_id = Some(id);
680680
}
681681
let request = GetDigestsTtlRequest {

app/buck2_execute_impl/src/executors/action_cache.rs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,12 @@ async fn query_action_cache_and_download_result(
107107
)
108108
.await;
109109

110-
let identity = Some(ReActionIdentity::new(
110+
let identity = ReActionIdentity::new(
111111
command.target,
112112
re_action_key.as_deref(),
113113
command.request.paths(),
114114
Some(action_digest.raw_digest().to_string()),
115-
));
115+
);
116116
if upload_all_actions {
117117
match re_client
118118
.upload(
@@ -121,7 +121,7 @@ async fn query_action_cache_and_download_result(
121121
action_blobs,
122122
ProjectRelativePath::empty(),
123123
request.paths().input_directory(),
124-
identity.as_ref(),
124+
&identity,
125125
digest_config,
126126
deduplicate_get_digests_ttl_calls,
127127
)
@@ -168,13 +168,6 @@ async fn query_action_cache_and_download_result(
168168
}
169169
};
170170

171-
let identity = ReActionIdentity::new(
172-
command.target,
173-
re_action_key.as_deref(),
174-
command.request.paths(),
175-
Some(action_digest.raw_digest().to_string()),
176-
);
177-
178171
let response = ActionCacheResult(response, cache_type.to_proto());
179172
let res = download_action_results(
180173
request,

app/buck2_execute_impl/src/executors/action_cache_upload_permission_checker.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use buck2_error::BuckErrorContext;
1818
use buck2_execute::digest_config::DigestConfig;
1919
use buck2_execute::re::client::ActionCacheWriteType;
2020
use buck2_execute::re::error::RemoteExecutionError;
21+
use buck2_execute::re::action_identity::ReActionIdentity;
2122
use buck2_execute::re::manager::ManagedRemoteExecutionClient;
2223
use dashmap::DashMap;
2324
use dupe::Dupe;
@@ -58,9 +59,18 @@ impl ActionCacheUploadPermissionChecker {
5859
) -> buck2_error::Result<Result<(), String>> {
5960
let (action, action_result) = empty_action_result(platform, digest_config)?;
6061

61-
// This is CAS upload, if it fails, something is very broken.
62+
// This is CAS upload for permission check with a synthetic empty action.
63+
let identity = ReActionIdentity::minimal(
64+
"CASPermCheck".to_owned(),
65+
Some("CASPermCheck".to_owned()),
66+
);
6267
re_client
63-
.upload_files_and_directories(Vec::new(), Vec::new(), action.blobs.to_inlined_blobs())
68+
.upload_files_and_directories(
69+
Vec::new(),
70+
Vec::new(),
71+
action.blobs.to_inlined_blobs(),
72+
&identity,
73+
)
6474
.await?;
6575

6676
// This operation requires permission to write.

app/buck2_execute_impl/src/executors/caching.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,13 @@ impl CacheUploader {
137137
return Ok(rejected);
138138
}
139139

140+
let identity = ReActionIdentity::new(
141+
info.target,
142+
None, // re_action_key not available in cache upload context
143+
info.paths,
144+
Some(digest.raw_digest().to_string()),
145+
);
146+
140147
// upload Action to CAS.
141148
// This is necessary when writing to the ActionCache through CAS, since CAS needs to inspect the Action related to the ActionResult.
142149
// Without storing the Action itself to CAS, ActionCache writes would fail.
@@ -145,6 +152,7 @@ impl CacheUploader {
145152
vec![],
146153
vec![],
147154
action_digest_and_blobs.blobs.to_inlined_blobs(),
155+
&identity,
148156
)
149157
.await?;
150158

@@ -254,6 +262,13 @@ impl CacheUploader {
254262
};
255263
action_result.execution_metadata.auxiliary_metadata = vec![dep_file_tany];
256264

265+
let identity = ReActionIdentity::new(
266+
info.target,
267+
None, // re_action_key not available in cache upload context
268+
info.paths,
269+
Some(digest.raw_digest().to_string()),
270+
);
271+
257272
// upload Action to CAS.
258273
// This is necessary when writing to the ActionCache through CAS, since CAS needs to inspect the Action related to the ActionResult.
259274
// Without storing the Action itself to CAS, ActionCache writes would fail.
@@ -262,6 +277,7 @@ impl CacheUploader {
262277
vec![],
263278
vec![],
264279
remote_dep_file_action.blobs.to_inlined_blobs(),
280+
&identity,
265281
)
266282
.await?;
267283

@@ -350,6 +366,16 @@ impl CacheUploader {
350366
..Default::default()
351367
});
352368

369+
// ReActionIdentity contains references so it cannot be moved into the async
370+
// block. Create it inside the closure instead. The action_id is precomputed
371+
// above to avoid repeated string allocations.
372+
let identity = ReActionIdentity::new(
373+
info.target,
374+
None, // re_action_key not available in cache upload context
375+
info.paths,
376+
Some(action_id.clone()),
377+
);
378+
353379
let fut = async move {
354380
let name = self
355381
.artifact_fs
@@ -367,6 +393,7 @@ impl CacheUploader {
367393
}],
368394
vec![],
369395
vec![],
396+
&identity,
370397
)
371398
.await
372399
};
@@ -404,7 +431,7 @@ impl CacheUploader {
404431
&action_blobs,
405432
output.path(),
406433
&d.dupe().as_immutable(),
407-
Some(&identity),
434+
&identity,
408435
digest_config,
409436
self.deduplicate_get_digests_ttl_calls,
410437
)

app/buck2_execute_impl/src/executors/re.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ impl ReExecutor {
110110
blobs,
111111
ProjectRelativePath::empty(),
112112
paths.input_directory(),
113-
Some(identity),
113+
identity,
114114
digest_config,
115115
self.deduplicate_get_digests_ttl_calls,
116116
)

0 commit comments

Comments
 (0)